The problem I'm having: CreateFile returns a handle of 0x194. ReadFileEx is saying that this handle is invalid. (Error 6.) Any ideas? The argument passed in is "C:\testfile.txt", which is a valid text file I made in Notepad. Despite being a C++ programmer for the last 12 years, this is my first time writing anything with "windows.h" or threads.
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
using namespace System;
int main(int argc, char **argv)
{
if (argc != 2)
{
printf("To display a file, you must enter the filename as the only command argument.");
scanf("\n");
return 0;
}
HANDLE file;
int nameLen = (strlen(argv[1]) + 1);
wchar_t *filename = new wchar_t[nameLen];
if (filename == 0)
{
printf("To display a file, you must enter the filename as the only command argument.");
scanf("\n");
return 0;
}
memset(filename, 0, nameLen);
::MultiByteToWideChar(CP_ACP, NULL, argv[1], -1, filename, nameLen);
file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == NULL)
{
printf("A valid filename is required.");
scanf("\n");
return 0;
}
char *buffer;
buffer = new char[1024];
OVERLAPPED overlapped;
overlapped.Offset = overlapped.OffsetHigh = 0;
ReadFileEx(file, &buffer, 1024, &overlapped, NULL);
WaitForSingleObject(&file, 0);
if (GetLastError() != ERROR_SUCCESS)
{
printf("A valid file is required., Error: %d", GetLastError());
scanf("\n");
return 0;
}
printf("%s", buffer);
scanf("\n");
delete buffer;
return 0;
}
My guess is to change
ReadFileEx(&file, &buffer, 1024, &overlapped, NULL);
to
ReadFileEx(file, &buffer, 1024, &overlapped, NULL);
Related
I wrote this code to encrypt a file in python with AES and now I send this file over HTTP to a client in C++ using Windows OS. And I want to decrypt this file on the C++ client, but I haven't found any libraries/usefull code to help me with this manner.
Here is the code for python:
def derive_key_and_iv(password, salt, key_length, iv_length):
d = d_i = b''
while len(d) < key_length + iv_length:
d_i = md5(d_i + str.encode(password) + salt).digest()
d += d_i
return d[:key_length], d[key_length:key_length + iv_length]
def encrypt(in_file, out_file, password, key_length=32):
bs = AES.block_size # 16 bytes
salt = urandom(bs)
key, iv = derive_key_and_iv(password, salt, key_length, bs)
cipher = AES.new(key, AES.MODE_CBC, iv)
out_file.write(salt)
finished = False
while not finished:
chunk = in_file.read(1024 * bs)
if len(chunk) == 0 or len(chunk) % bs != 0: #final block
padding_length = (bs - len(chunk) % bs) or bs
chunk += str.encode(padding_length * chr(padding_length))
finished = True
out_file.write(cipher.encrypt(chunk))
password = 'ABCDE' # some password
with open("some_file.bin", "rb") as in_file, open("enc_some_file.enc", "wb") as out_file:
encrypt(in_file, out_file, password)
Update:
I am updating this question regarding my try with WinCrypt. I am trying to compile from VS CODE using MSYS64 g++ compiler on Windows. Here is the code that I am trying to run. I also have some additional libraries to help me with the client-server part, such as libcurlpp and libcurl.
#include <string>
#include <sstream>
#include <conio.h>
#include <iostream>
#include <fstream>
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <wincrypt.h>
#include <windows.h>
#define AES_KEY_SIZE 32
#define IN_CHUNK_SIZE (AES_KEY_SIZE * 10) // a buffer must be a multiple of the key size
#define OUT_CHUNK_SIZE (IN_CHUNK_SIZE * 2) // an output buffer (for encryption) must be twice as big
using namespace std;
string host = ""; #some host
int main(void)
{
curlpp::Easy req;
req.setOpt(new curlpp::options::Url(host));
ofstream myfile;
myfile.open("enc_calc.enc", ios::out | ios::binary);
myfile << req;
myfile.close();
getch();
wchar_t *in_file = (wchar_t *)"enc_calc.enc";
wchar_t *out_file = (wchar_t *)"calc.dll";
wchar_t default_key[] = L"ABCDE";
wchar_t *key_str = default_key;
const size_t len = lstrlenW(key_str);
const size_t key_size = len * sizeof(key_str[0]);
const wchar_t *filename1 = (const wchar_t *)"enc_calc.enc";
const wchar_t *filename2 = (const wchar_t *)"calc.dll";
HANDLE hInpFile = CreateFileW(filename1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hInpFile == INVALID_HANDLE_VALUE) {
printf("Cannot open input file!\n");
system("pause");
return (-1);
}
HANDLE hOutFile = CreateFileW(filename2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutFile == INVALID_HANDLE_VALUE) {
printf("Cannot open output file!\n");
system("pause");
return (-1);
}
DWORD dwStatus = 0;
BOOL bResult = FALSE;
wchar_t info[] = L"Microsoft Enhanced RSA and AES Cryptographic Provider";
HCRYPTPROV hProv;
if (!CryptAcquireContextW(&hProv, NULL, info, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %x\n", dwStatus);
CryptReleaseContext(hProv, 0);
system("pause");
return dwStatus;
}
HCRYPTHASH hHash;
if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
dwStatus = GetLastError();
printf("CryptCreateHash failed: %x\n", dwStatus);
CryptReleaseContext(hProv, 0);
system("pause");
return dwStatus;
}
if (!CryptHashData(hHash, (BYTE*)key_str, key_size, 0)) {
DWORD err = GetLastError();
printf("CryptHashData Failed : %#x\n", err);
system("pause");
return (-1);
}
printf("[+] CryptHashData Success\n");
HCRYPTKEY hKey;
if (!CryptDeriveKey(hProv, CALG_AES_128, hHash, 0, &hKey)) {
dwStatus = GetLastError();
printf("CryptDeriveKey failed: %x\n", dwStatus);
CryptReleaseContext(hProv, 0);
system("pause");
return dwStatus;
}
printf("[+] CryptDeriveKey Success\n");
const size_t chunk_size = IN_CHUNK_SIZE;
BYTE *chunk = new BYTE[chunk_size];
DWORD out_len = 0;
BOOL isFinal = FALSE;
DWORD readTotalSize = 0;
DWORD inputSize = GetFileSize(hInpFile, NULL);
while (bResult = ReadFile(hInpFile, chunk, IN_CHUNK_SIZE, &out_len, NULL)) {
if (0 == out_len) {
break;
}
readTotalSize += out_len;
if (readTotalSize >= inputSize) {
isFinal = TRUE;
printf("Final chunk set, len: %d = %x\n", out_len, out_len);
}
if (!CryptDecrypt(hKey, NULL, isFinal, 0, chunk, &out_len)) {
printf("[-] CryptDecrypt failed: %x\n", GetLastError());
break;
}
DWORD written = 0;
if (!WriteFile(hOutFile, chunk, out_len, &written, NULL)) {
printf("writing failed!\n");
break;
}
memset(chunk, 0, chunk_size);
}
delete[]chunk; chunk = NULL;
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
CloseHandle(hInpFile);
CloseHandle(hOutFile);
printf("Finished. Processed %#x bytes.\n", readTotalSize);
return 0;
}
The errors I'm getting are regarding the windows.h library, such as:
"ULONG does not name a type" and other types in windows. and at runtime: "Cannot Open input file", not sure why, even tho the file is downloaded in the current folder and I'm trying to open it as such in the code.
Suppose I have a usb drive with two partition e:, f:. How do I know from which offset the partition e: or f: starts so that I can write raw data starting from that offset. I could not find any function that would provide me the offset in c++. In Dos I could easily get this with wmic partition get Index, Name, StartingOffset.
To get the StartingOffset of partitions in a Physical Drive(such as \\\\.\\PhysicalDrive1), you could use IOCTL_DISK_GET_DRIVE_LAYOUT_EX to get PARTITION_INFORMATION_EX arrays for each partition:
#include <windows.h>
#include <stdio.h>
#define wszDrive L"\\\\.\\PhysicalDrive1"
int wmain(int argc, wchar_t* argv[])
{
HANDLE hDevice = INVALID_HANDLE_VALUE; // handle to the drive to be examined
BOOL bResult = FALSE; // results flag
DWORD junk = 0; // discard results
DWORD error;
DWORD szNewLayout = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + sizeof(PARTITION_INFORMATION_EX) * 4 * 25;
hDevice = CreateFileW(wszDrive, // drive to open
GENERIC_READ, // no access to the drive
FILE_SHARE_READ,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
0); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
error = GetLastError();
printf("CreateFileW error: %d\n", error);
return -1;
}
DRIVE_LAYOUT_INFORMATION_EX* pdg = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(szNewLayout);
if (pdg == NULL)
{
error = GetLastError();
printf("malloc error: %d\n", error);
CloseHandle(hDevice);
return -1;
}
ZeroMemory(pdg, szNewLayout);
bResult = DeviceIoControl(hDevice, // device to be queried
IOCTL_DISK_GET_DRIVE_LAYOUT_EX, // operation to perform
NULL, 0, // no input buffer
pdg, szNewLayout,// sizeof(*pdg)*2, // output buffer
&junk, // # bytes returned
(LPOVERLAPPED)NULL); // synchronous I/O
if (!bResult)
{
error = GetLastError();
printf("DeviceIoControl error: %d\n", error);
free(pdg);
CloseHandle(hDevice);
return -1;
}
for (int i = 0; i < pdg->PartitionCount; i++) {
printf("partition %d: %lld\n", i, pdg->PartitionEntry[i].StartingOffset.QuadPart);
}
free(pdg);
CloseHandle(hDevice);
return 0;
}
To get the StartingOffset of a specified partition(such as \\\\.\\E:), you could use IOCTL_DISK_GET_PARTITION_INFO_EX:
#include <windows.h>
#include <stdio.h>
#define wszDrive L"\\\\.\\E:"
int wmain(int argc, wchar_t* argv[])
{
HANDLE hDevice = INVALID_HANDLE_VALUE; // handle to the drive to be examined
BOOL bResult = FALSE; // results flag
DWORD junk = 0; // discard results
DWORD error;
PARTITION_INFORMATION_EX piex;
ZeroMemory(&piex, sizeof(PARTITION_INFORMATION_EX));
hDevice = CreateFileW(wszDrive, // drive to open
GENERIC_READ, // no access to the drive
FILE_SHARE_READ,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
0); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
error = GetLastError();
printf("CreateFileW error: %d\n", error);
return -1;
}
bResult = DeviceIoControl(hDevice,
IOCTL_DISK_GET_PARTITION_INFO_EX,
NULL, 0,
&piex, sizeof(PARTITION_INFORMATION_EX),
&junk,
(LPOVERLAPPED)NULL);
if (!bResult)
{
error = GetLastError();
printf("DeviceIoControl error: %d\n", error);
CloseHandle(hDevice);
return -1;
}
wprintf(L"%s StartingOffset: %lld\n", wszDrive, piex.StartingOffset.QuadPart);
CloseHandle(hDevice);
return 0;
}
I'm trying to open a file on windows and check that the magic bytes match a windows PE32. If I run the code below and return just before the ReadFile call in the function problemFunction the code works fine and it prints 5a4d at the end of the main function. However if I return after the ReadFile call in problemFunction then I exit in the dos->e_magic != PIMAGE_DOS_HEADER check.
#include <Windows.h>
#include <winternl.h>
void problemFunction(HANDLE *fh) {
DWORD fileSize = GetFileSize(fh, NULL);
if (!fileSize) { CloseHandle(fh); exit(1); }
BYTE* pByte = new BYTE[fileSize];
DWORD dw;
ReadFile(*fh, pByte, fileSize, &dw, NULL);
// could be wrong but i think i need to run SetFilePointer here but not sure on what to do.
return;
}
int main() {
const char* filepath = "C:\\windows\\file\\path\\to\\exe";
HANDLE fh = CreateFileA(filepath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(fh == INVALID_HANDLE_VALUE) { CloseHandle(fh); exit(1); }
problemFunction(&fh);
DWORD fileSize = GetFileSize(fh, NULL);
if (!fileSize) { CloseHandle(fh); exit(1); }
BYTE* pByte = new BYTE[fileSize];
DWORD dw;
ReadFile(fh, pByte, fileSize, &dw, NULL);
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)pByte;
if (dos->e_magic != IMAGE_DOS_SIGNATURE) { CloseHandle(fh); exit(1); }
// dos->e_magic should be 5a4d for MZ, windows PE
}
I assume i need to reset the file pointer after the problemFunction read call with something like
LONG reset = -sizeof(DWORD);
SetFilePointer(*fh, reset, NULL, FILE_END);
But i can't get it to work.
Thanks
There are a number of problems with your code.
problemFunction() is taking a HANDLE* pointer as input, but it is not dereferencing that pointer when passing it to GetFileSize() or CloseHandle(). But it is dereferencing the pointer when passing it to ReadFile().
You must be compiling your code with STRICT Type Checking turned off, otherwise your code would fail to compile. You should always compile with STRICT enabled.
HANDLE is a pointer type, so there is no need to pass it around by pointer, unless you are going to modify its value, which this code is not doing. So you should change problemFunction() to take a HANDLE as-is rather than taking a HANDLE* pointer.
Also, GetFileSize() does not return 0 on failure, like your code assumes. It actually returns INVALID_FILE_SIZE which is -1, ie 0XFFFFFFFF as a DWORD. This is clearly stated in the documentation:
If the function fails and lpFileSizeHigh is NULL, the return value is INVALID_FILE_SIZE. To get extended error information, call GetLastError.
But, most importantly, your 2nd call to ReadFile() inside of main() does not read what you are expecting because the 1st call to ReadFile() inside of problemFunction() has already read the data (and leaked it!), but you are not seeking the HANDLE back to the beginning of the file after that read so the 2nd call to ReadFile() can read it again. You are correct that you need to use SetFilePointer() for that.
With that said, try something more like this:
#include <Windows.h>
#include <winternl.h>
bool test(HANDLE fh) {
DWORD fileSize = GetFileSize(fh, NULL);
if (fileSize == INVALID_FILE_SIZE) {
return false;
}
BYTE* pByte = new BYTE[fileSize];
DWORD dw;
if (!ReadFile(fh, pByte, fileSize, &dw, NULL)) {
delete[] pByte;
return false;
}
// use pByte as needed...
delete[] pByte;
if (SetFilePointer(fh, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
return false;
}
return true;
}
int main() {
const char* filepath = "C:\\windows\\file\\path\\to\\exe";
HANDLE fh = CreateFileA(filepath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh == INVALID_HANDLE_VALUE) {
return 1;
}
if (!test(fh)) {
CloseHandle(fh);
return 1;
}
DWORD fileSize = GetFileSize(fh, NULL);
if (fileSize == INVALID_FILE_SIZE) {
CloseHandle(fh);
return 1;
}
BYTE* pByte = new BYTE[fileSize];
DWORD dw;
if (!ReadFile(fh, pByte, fileSize, &dw, NULL) || dw < sizeof(IMAGE_DOS_HEADER)) {
CloseHandle(fh);
return 1;
}
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)pByte;
if (dos->e_magic != IMAGE_DOS_SIGNATURE) {
delete[] pByte;
CloseHandle(fh);
return 1;
}
...
delete[] pByte;
CloseHandle(fh);
return 0;
}
this is my code :
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <Windows.h>
#include <stdio.h>
#include <iostream>
int main(int argc, CHAR* argv[]) {
PVOID data[1024];
DWORD dwBytesRead = 0;
DWORD dwBytesWrite = 512;
HANDLE hFile = CreateFile(L"\\\\.\\E:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE) {
printf("Error %x", GetLastError());
return 1;
}
PVOID ToBe = "hello world from usb";
if (WriteFile(hFile,&ToBe,512,&dwBytesWrite, NULL) == 0)
{
printf("writeFile error: %x", GetLastError());
return 1;
}
while (ReadFile(hFile, &data, 512, &dwBytesRead, NULL) != 0) {
printf("%s", data);
}
if (ReadFile(hFile, &data, 512, &dwBytesRead, NULL) == 0) {
printf("ReadFile error: %x", GetLastError());
return 1;
}
return 0;
}
Now it looks like working, but I can't see the "hello world" in the USB...
what I did wrong?
(p.s. after I run the program I can't open my USB again without formating him, so something indeed got written, but I can't see it with the radial function right after that...)
You write 512 bytes, and that advances the file pointer by 512 bytes. You then read from that point. Instead you need to seek the file pointer back to the beginning. Use SetFilePointerEx to do that.
i'm traing to do 2 process that do this:
Process A (the client) :
- It opens a temporary file for writing (use GetTempFileName to
obtain a unique file name).
- It starts Process B passing as argument the name of the file.
- It reads from standard input strings of characters, and it writes
those strings on the intermediate file.
Use string of constant length (e.g., #define MAX_LEN 100).
- It stops reading strings from standard input when it receives an
end-of-file (ctrl-Z).
- Before terminating, it writes the string
".end"
as last line of the file.
Process B (the server) works as follows:
- It opens the intermediate file for reading.
- It reads lines as soon as they are available, and it prints them
out on standard output.
Process A keeps the file open, and it always locks the next part of
the file before unlocking the previous part.
Process B runs in parallel, and it reads a shared file, waiting to
have access to single lines to read them.
but seams that the ReadFile on process B do not wait until the fileLock is removed so it terminate befor the first line is inserted
process A:
#include <windows.h>
#include <process.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <io.h>
#define MAX_LEN 100
int _tmain(int argc, LPTSTR argv[]){
TCHAR tmpFileName[MAX_PATH];
TCHAR tmppath[MAX_PATH];
TCHAR moment[MAX_PATH];
TCHAR command[MAX_PATH + 256];
UINT uRetVal = 0;
HANDLE bufferW,next;
DWORD n;
PROCESS_INFORMATION piS;
STARTUPINFO siS;
TCHAR buffer[MAX_LEN];
int i=0;
OVERLAPPED ov = { 0, 0, 0, 0, NULL };
LARGE_INTEGER FilePos;
ZeroMemory(&siS, sizeof(siS));
siS.cb = sizeof(siS);
ZeroMemory(&piS, sizeof(piS));
uRetVal = GetTempFileName(_T("."), // directory for tmp files
_T(""), // temp file name prefix
0, // create unique name
tmpFileName); // buffer for name
if (uRetVal == 0)
{
_tprintf("\n errore apertura temp file");
return (3);
}
GetCurrentDirectory(MAX_PATH, moment);
//_stprintf(tmppath, "%s\\ %s",moment,tmpFileName);
_tprintf("\n CLIENT PATH %s \n",moment);
//_stprintf(command,"%s %s","C:\\Users\\zio gianni\\Documents\\Visual Studio 2013\\Projects\\lab11server\\Debug\\lab11server.exe",tmpFileName);
_stprintf(command, "%s %s", "server.exe", tmpFileName);
bufferW = CreateFile(tmpFileName, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
next = CreateFile(tmpFileName, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (next == INVALID_HANDLE_VALUE) {
_tprintf(_T("Cannot open client file. Error: %x\n"),
GetLastError());
_tprintf(" \n Nome File: %s\n", "./prova.bin");
return 2;
}
if (bufferW == INVALID_HANDLE_VALUE) {
_tprintf(_T("Cannot open client file. Error: %x\n"),
GetLastError());
_tprintf(" \n Nome File: %s\n", "./prova.bin");
return 2;
}
FilePos.QuadPart = i*MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;
LockFileEx(bufferW, LOCKFILE_EXCLUSIVE_LOCK, 0, FilePos.LowPart, FilePos.HighPart, &ov);
printf("file bloccato avvio server con comand: %s\n", command);
if (!CreateProcess(NULL, // No module name (use command line)
command, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
TRUE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&siS, // Pointer to STARTUPINFO structure
&piS) // Pointer to PROCESS_INFORMATION structure
)
{
printf("CreateProcess failed (%d).\n", GetLastError());
return -5;
}
while (TRUE){
scanf("%s",buffer);
if (strcmp(buffer, "EOF")==0){
break;
}
WriteFile(bufferW, buffer, MAX_LEN*sizeof(TCHAR), &n, NULL);
FilePos.QuadPart =(i+1)* MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;
if (i % 2 == 0){
LockFile(next, LOCKFILE_EXCLUSIVE_LOCK, 0, FilePos.LowPart, FilePos.HighPart, &ov);
FilePos.QuadPart = (i )* MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;
UnlockFile(bufferW, 0, 0, 0, &ov);
}
else{
LockFile(bufferW, LOCKFILE_EXCLUSIVE_LOCK, 0, FilePos.LowPart, FilePos.HighPart, &ov);
FilePos.QuadPart = (i )* MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;
UnlockFile(next, 0, 0, 0, &ov);
}
i++;
}
sprintf(buffer, ".end");
WriteFile(bufferW, buffer, MAX_LEN*sizeof(TCHAR), &n ,NULL);
if (i % 2 == 0){
FilePos.QuadPart = (i)* MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;
UnlockFile(bufferW, 0, FilePos.LowPart, FilePos.HighPart, &ov);
}
else{
FilePos.QuadPart = (i)* MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;
UnlockFile(next, 0, FilePos.LowPart, FilePos.HighPart, &ov);
}
// Wait until child process exits.
WaitForSingleObject(piS.hProcess, INFINITE);
// Close process and thread handles.
CloseHandle(piS.hProcess);
CloseHandle(piS.hThread);
return 0;
}
process B:
#include <windows.h>
#include <process.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <io.h>
#define MAX_LEN 100
int _tmain(int argc, LPTSTR argv[]){
HANDLE read;
DWORD n;
int i = 0;
TCHAR buffer[MAX_LEN], path[MAX_LEN];
OVERLAPPED ov = { 0, 0, 0, 0, NULL };
LARGE_INTEGER FilePos;
read = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (read == INVALID_HANDLE_VALUE) {
_tprintf(_T("Cannot open input file. Error: %x\n"),
GetLastError());
_tprintf(" \n Nome File: %s\n", argv[1]);
return 2;
}
_tprintf(" \n Nome File APERTO: %s\n", argv[1]);
GetCurrentDirectory(MAX_LEN,path);
_tprintf(" \n path server: %s\n%s\n", path,argv[1]);
while (ReadFile(read, buffer, MAX_LEN*sizeof(TCHAR), &n, &ov) && n>0 ){
if (n == 0){
fprintf(stderr,"error readfle\n");
return -5;
}
if (strncmp(buffer, ".end", 4) == 0){
_tprintf(" \n STAMPA SERVER: esco\n");
break;
}
_tprintf(" \n STAMPA SERVER: %s\n", buffer);
}
if (n == 0){
fprintf(stderr, "error readfle\n");
return -5;
}
_tprintf("\n END SERVER");
return 0;
}
Do not use actual files for inter process communication. Use named pipes!
Search for CreateNamedPipe, there are plenty of examples.