diff --git a/dll/win32/kernel32/client/file/rw.c b/dll/win32/kernel32/client/file/rw.c index 8fc10d2ae37..f617d640976 100644 --- a/dll/win32/kernel32/client/file/rw.c +++ b/dll/win32/kernel32/client/file/rw.c @@ -20,12 +20,14 @@ DEBUG_CHANNEL(kernel32file); /* * @implemented */ -BOOL WINAPI -WriteFile(IN HANDLE hFile, - IN LPCVOID lpBuffer, - IN DWORD nNumberOfBytesToWrite OPTIONAL, - OUT LPDWORD lpNumberOfBytesWritten, - IN LPOVERLAPPED lpOverlapped OPTIONAL) +BOOL +WINAPI +WriteFile( + _In_ HANDLE hFile, + _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer, + _In_ DWORD nNumberOfBytesToWrite, + _Out_opt_ LPDWORD lpNumberOfBytesWritten, + _Inout_opt_ LPOVERLAPPED lpOverlapped) { NTSTATUS Status; @@ -76,7 +78,7 @@ WriteFile(IN HANDLE hFile, } else { - IO_STATUS_BLOCK Iosb; + IO_STATUS_BLOCK Iosb = { 0 }; Status = NtWriteFile(hFile, NULL, @@ -96,11 +98,13 @@ WriteFile(IN HANDLE hFile, } /* - * lpNumberOfBytesWritten must not be NULL here, in fact Win doesn't - * check that case either and crashes (only after the operation - * completed). + * Windows 2003 and Vista do not check for lpNumberOfBytesWritten == NULL, + * but Windows 8+ does and Wine code (crypt32) relies on this. + * We ignore Hyrum's Law and assume that crashing here is not a + * behavior that software relies on. */ - *lpNumberOfBytesWritten = Iosb.Information; + if (lpNumberOfBytesWritten != NULL) + *lpNumberOfBytesWritten = Iosb.Information; if (!NT_SUCCESS(Status)) { @@ -117,12 +121,14 @@ WriteFile(IN HANDLE hFile, /* * @implemented */ -BOOL WINAPI -ReadFile(IN HANDLE hFile, - IN LPVOID lpBuffer, - IN DWORD nNumberOfBytesToRead, - OUT LPDWORD lpNumberOfBytesRead OPTIONAL, - IN LPOVERLAPPED lpOverlapped OPTIONAL) +BOOL +WINAPI +ReadFile( + _In_ HANDLE hFile, + _Out_writes_bytes_to_opt_(nNumberOfBytesToRead, *lpNumberOfBytesRead) __out_data_source(FILE) LPVOID lpBuffer, + _In_ DWORD nNumberOfBytesToRead, + _Out_opt_ LPDWORD lpNumberOfBytesRead, + _Inout_opt_ LPOVERLAPPED lpOverlapped) { NTSTATUS Status; @@ -187,7 +193,7 @@ ReadFile(IN HANDLE hFile, } else { - IO_STATUS_BLOCK Iosb; + IO_STATUS_BLOCK Iosb = { 0 }; Status = NtReadFile(hFile, NULL, @@ -209,20 +215,20 @@ ReadFile(IN HANDLE hFile, if (Status == STATUS_END_OF_FILE) { /* - * lpNumberOfBytesRead must not be NULL here, in fact Win doesn't - * check that case either and crashes (only after the operation - * completed). + * Windows 2003 and Vista do not check for lpNumberOfBytesRead == NULL, + * but Windows 8+ does. Avoid crashing. */ - *lpNumberOfBytesRead = 0; + if (lpNumberOfBytesRead != NULL) + *lpNumberOfBytesRead = 0; return TRUE; } /* - * lpNumberOfBytesRead must not be NULL here, in fact Win doesn't - * check that case either and crashes (only after the operation - * completed). + * Windows 2003 and Vista do not check for lpNumberOfBytesRead == NULL, + * but Windows 8+ does. Avoid crashing. */ - *lpNumberOfBytesRead = Iosb.Information; + if (lpNumberOfBytesRead != NULL) + *lpNumberOfBytesRead = Iosb.Information; if (!NT_SUCCESS(Status)) {