// PELF_FILE_READ_ROUTINE static NTSTATUS NTAPI LogfpReadFile(IN PEVTLOGFILE LogFile, IN PLARGE_INTEGER FileOffset, OUT PVOID Buffer, IN SIZE_T Length, OUT PSIZE_T ReadLength OPTIONAL) { NTSTATUS Status; PLOGFILE pLogFile = (PLOGFILE)LogFile; IO_STATUS_BLOCK IoStatusBlock; if (ReadLength) *ReadLength = 0; Status = NtReadFile(pLogFile->FileHandle, NULL, NULL, NULL, &IoStatusBlock, Buffer, Length, FileOffset, NULL); if (ReadLength) *ReadLength = IoStatusBlock.Information; return Status; }
VOID readfile ( HANDLE handle, ULONG offset, ULONG len, PVOID buffer ) { NTSTATUS status; IO_STATUS_BLOCK iosb; LARGE_INTEGER foffset; foffset = RtlConvertUlongToLargeInteger(offset); status = NtReadFile ( handle, NULL, // event NULL, // apc routine NULL, // apc context &iosb, buffer, len, &foffset, NULL ); if (!NT_SUCCESS(status)) { RtlRaiseStatus (1); } }
/* * @implemented */ BOOL WINAPI ReadFileEx(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { LARGE_INTEGER Offset; NTSTATUS Status; Offset.u.LowPart = lpOverlapped->Offset; Offset.u.HighPart = lpOverlapped->OffsetHigh; lpOverlapped->Internal = STATUS_PENDING; Status = NtReadFile(hFile, NULL, ApcRoutine, lpCompletionRoutine, (PIO_STATUS_BLOCK)lpOverlapped, lpBuffer, nNumberOfBytesToRead, &Offset, NULL); if (!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); return FALSE; } return TRUE; }
BOOL WINAPI FlushConsoleInputBuffer( IN HANDLE hConsoleInput) { LARGE_INTEGER Offset, Timeout; IO_STATUS_BLOCK IoStatusBlock; KEYBOARD_INPUT_DATA InputData; NTSTATUS Status; do { Offset.QuadPart = 0; Status = NtReadFile(hConsoleInput, NULL, NULL, NULL, &IoStatusBlock, &InputData, sizeof(KEYBOARD_INPUT_DATA), &Offset, 0); if (Status == STATUS_PENDING) { Timeout.QuadPart = -100; Status = NtWaitForSingleObject(hConsoleInput, FALSE, &Timeout); if (Status == STATUS_TIMEOUT) { NtCancelIoFile(hConsoleInput, &IoStatusBlock); return TRUE; } } } while (NT_SUCCESS(Status)); return FALSE; }
PUCHAR PhpReadSignature( _In_ PWSTR FileName, _Out_ PULONG SignatureSize ) { NTSTATUS status; HANDLE fileHandle; PUCHAR signature; ULONG bufferSize; IO_STATUS_BLOCK iosb; if (!NT_SUCCESS(PhCreateFileWin32(&fileHandle, FileName, FILE_GENERIC_READ, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT))) { return NULL; } bufferSize = 1024; signature = PhAllocate(bufferSize); status = NtReadFile(fileHandle, NULL, NULL, NULL, &iosb, signature, bufferSize, NULL, NULL); NtClose(fileHandle); if (NT_SUCCESS(status)) { *SignatureSize = (ULONG)iosb.Information; return signature; } else { PhFree(signature); return NULL; } }
BOOL ReadBlock(HANDLE FileHandle, PVOID Buffer, PLARGE_INTEGER Offset, ULONG Length, PULONG BytesRead) { IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE EventHandle; InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtCreateEvent(&EventHandle, EVENT_ALL_ACCESS, &ObjectAttributes, TRUE, FALSE); if (!NT_SUCCESS(Status)) { printf("NtCreateEvent() failed\n"); return(FALSE); } Status = NtReadFile(FileHandle, EventHandle, NULL, NULL, &IoStatusBlock, Buffer, Length, Offset, NULL); if (Status == STATUS_PENDING) { NtWaitForSingleObject(EventHandle, FALSE, NULL); Status = IoStatusBlock.Status; } NtClose(EventHandle); if (Status != STATUS_PENDING && BytesRead != NULL) { *BytesRead = IoStatusBlock.Information; } if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE) { printf("ReadBlock() failed (Status: %lx)\n", Status); return(FALSE); } return(TRUE); }
static NTSTATUS PhpRfThreadStart( _In_ PVOID Parameter ) { HANDLE fileHandle; IO_STATUS_BLOCK isb; ULONG data; fileHandle = Parameter; NtReadFile(fileHandle, NULL, NULL, NULL, &isb, &data, sizeof(ULONG), NULL, NULL); return STATUS_SUCCESS; }
static NTSTATUS NetworkWorkerThreadStart( __in PVOID Parameter ) { NTSTATUS status; PNETWORK_OUTPUT_CONTEXT context = Parameter; IO_STATUS_BLOCK isb; UCHAR buffer[4096]; while (TRUE) { status = NtReadFile( context->PipeReadHandle, NULL, NULL, NULL, &isb, buffer, sizeof(buffer), NULL, NULL ); PhAcquireQueuedLockExclusive(&context->WindowHandleLock); if (!context->WindowHandle) { PhReleaseQueuedLockExclusive(&context->WindowHandleLock); goto ExitCleanup; } if (!NT_SUCCESS(status)) { SendMessage(context->WindowHandle, NTM_DONE, 0, 0); PhReleaseQueuedLockExclusive(&context->WindowHandleLock); goto ExitCleanup; } SendMessage(context->WindowHandle, NTM_RECEIVED, (WPARAM)isb.Information, (LPARAM)buffer); PhReleaseQueuedLockExclusive(&context->WindowHandleLock); } ExitCleanup: NtClose(context->PipeReadHandle); return STATUS_SUCCESS; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Reads or writes specified number of sectors from/to specified buffer. // static BOOL DirectIo( PWCHAR Drive, // drive name to read/write sectors from/to PCHAR Buffer, // bufer to store the data ULONG Length, // size of the buffer ULONG LBASector, // starting LBA sector ULONG Count, // number of sectors to read/write ULONG Flags // variouse operation flags ) { BOOL Ret = FALSE; HANDLE hDrive; NTSTATUS ntStatus; OBJECT_ATTRIBUTES oa = {0}; UNICODE_STRING us; IO_STATUS_BLOCK IoStatus = {0}; LARGE_INTEGER FilePos = {0}; HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); RtlInitUnicodeString(&us, Drive); InitializeObjectAttributes(&oa, &us, OBJ_CASE_INSENSITIVE, NULL, NULL); if ((Count * BIOS_DEFAULT_SECTOR_SIZE) <= Length) { ntStatus = NtCreateFile(&hDrive, GENERIC_WRITE | GENERIC_READ, &oa, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0); if (NT_SUCCESS(ntStatus)) { FilePos.QuadPart = ((ULONGLONG)LBASector * BIOS_DEFAULT_SECTOR_SIZE); if (Flags & SCSI_IO_WRITE_SECTOR) ntStatus = NtWriteFile(hDrive, hEvent, NULL, NULL, &IoStatus, Buffer, (Count*BIOS_DEFAULT_SECTOR_SIZE), &FilePos, NULL); else ntStatus = NtReadFile(hDrive, hEvent, NULL, NULL, &IoStatus, Buffer, (Count*BIOS_DEFAULT_SECTOR_SIZE), &FilePos, NULL); if (ntStatus == STATUS_PENDING) WaitForSingleObject(hEvent, INFINITE); NtClose(hDrive); if (NT_SUCCESS(IoStatus.Status)) Ret = TRUE; } // if (hDrive != INVALID_HANDLE_VALUE) } // if ((Count * BIOS_DEFAULT_SECTOR_SIZE) <= Length) return(Ret); }
/*++ * @name RtlClipWaitForInput * * The RtlClipWaitForInput routine waits for input from an input device. * * @param hDriver * Handle of the driver/device to get input from. * * @param Buffer * Input buffer. * * @param BufferSize * Size of the input buffer. * * @return STATUS_SUCCESS or error code from the read operation. * * @remarks This routine waits for input to be available. * *--*/ NTSTATUS RtlClipWaitForInput(IN HANDLE hDriver, IN PVOID Buffer, IN OUT PULONG BufferSize) { IO_STATUS_BLOCK Iosb; LARGE_INTEGER ByteOffset; NTSTATUS Status; // // Clean up the I/O Status block and read from byte 0 // RtlZeroMemory(&Iosb, sizeof(Iosb)); RtlZeroMemory(&ByteOffset, sizeof(ByteOffset)); // // Try to read the data // Status = NtReadFile(hDriver, hEvent, NULL, NULL, &Iosb, Buffer, *BufferSize, &ByteOffset, NULL); // // Check if data is pending // if (Status == STATUS_PENDING) { // // Wait on the data to be read // Status = NtWaitForSingleObject(hEvent, TRUE, NULL); } // // Return status and how much data was read // *BufferSize = (ULONG)Iosb.Information; return Status; }
NTSTATUS WINAPI SafeNtReadFile( HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key ) { NTSTATUS rc; if (CheckOldFunction(&OldNtReadFile)) rc=OldNtReadFile(FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,Buffer,Length,ByteOffset,Key); else rc=NtReadFile(FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,Buffer,Length,ByteOffset,Key); return rc; }
BOOL WINAPI ReadConsoleInput( IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead) { LARGE_INTEGER Offset; IO_STATUS_BLOCK IoStatusBlock; KEYBOARD_INPUT_DATA InputData; NTSTATUS Status; Offset.QuadPart = 0; Status = NtReadFile(hConsoleInput, NULL, NULL, NULL, &IoStatusBlock, &InputData, sizeof(KEYBOARD_INPUT_DATA), &Offset, 0); if (Status == STATUS_PENDING) { Status = NtWaitForSingleObject(hConsoleInput, FALSE, NULL); Status = IoStatusBlock.Status; } if (!NT_SUCCESS(Status)) return FALSE; lpBuffer->EventType = KEY_EVENT; Status = IntTranslateKey(&InputData, &lpBuffer->Event.KeyEvent); if (!NT_SUCCESS(Status)) return FALSE; *lpNumberOfEventsRead = 1; return TRUE; }
BOOLEAN ReadSector( HANDLE Handle, ULONG Lsn, PVOID Buffer, PULONG BytesRead ) { IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER ByteOffset; NTSTATUS nts; ByteOffset.HighPart = 0; ByteOffset.LowPart = Lsn; IoStatusBlock.Status = 0; IoStatusBlock.Information = 0; nts = NtReadFile( Handle, 0, NULL, NULL, &IoStatusBlock, Buffer, SectorSize, &ByteOffset, NULL ); if( !NT_SUCCESS( nts ) ) { printf( "Read failed.\n" ); printf( " Returned status: %lx\n", nts ); printf( " Final status: %lx\n", IoStatusBlock.Status ); return FALSE; } *BytesRead = IoStatusBlock.Information; return TRUE; }
int XReadFile( int handle, void *buffer, unsigned int numberOfBytesToRead, unsigned int *numberOfBytesRead) { IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; #ifdef DEBUG debugPrint("XReadFile handle=%08x numberOfBytesToRead=%08x\n", handle, numberOfBytesToRead); #endif if (numberOfBytesRead) *numberOfBytesRead = 0; status = NtReadFile( (void*)handle, NULL, NULL, NULL, (void*)&ioStatusBlock, (void*)buffer, numberOfBytesToRead, NULL); if (status == STATUS_SUCCESS) status = NtWaitForSingleObject((void*)handle, FALSE, (void*)NULL); if (!NT_SUCCESS(status)) return RtlNtStatusToDosError(status); else { if (numberOfBytesRead) *numberOfBytesRead = (unsigned int)ioStatusBlock.Information; return STATUS_SUCCESS; } }
NTSTATUS InfOpenFile(PHINF InfHandle, PUNICODE_STRING FileName, LANGID LanguageId, PULONG ErrorLine) { OBJECT_ATTRIBUTES ObjectAttributes; FILE_STANDARD_INFORMATION FileInfo; IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; NTSTATUS Status; PCHAR FileBuffer; ULONG FileLength; ULONG FileBufferLength; LARGE_INTEGER FileOffset; PINFCACHE Cache; CheckHeap(); *InfHandle = NULL; *ErrorLine = (ULONG)-1; /* Open the inf file */ InitializeObjectAttributes(&ObjectAttributes, FileName, 0, NULL, NULL); Status = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (!INF_SUCCESS(Status)) { DPRINT("NtOpenFile() failed (Status %lx)\n", Status); return(Status); } DPRINT("NtOpenFile() successful\n"); /* Query file size */ Status = NtQueryInformationFile(FileHandle, &IoStatusBlock, &FileInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!INF_SUCCESS(Status)) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return(Status); } FileLength = FileInfo.EndOfFile.u.LowPart; DPRINT("File size: %lu\n", FileLength); /* Allocate file buffer */ FileBufferLength = FileLength + 2; FileBuffer = MALLOC(FileBufferLength); if (FileBuffer == NULL) { DPRINT1("MALLOC() failed\n"); NtClose(FileHandle); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Read file */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, FileBuffer, FileLength, &FileOffset, NULL); /* Append string terminator */ FileBuffer[FileLength] = 0; FileBuffer[FileLength + 1] = 0; NtClose(FileHandle); if (!INF_SUCCESS(Status)) { DPRINT("NtReadFile() failed (Status %lx)\n", Status); FREE(FileBuffer); return(Status); } /* Allocate infcache header */ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); if (Cache == NULL) { DPRINT("MALLOC() failed\n"); FREE(FileBuffer); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Initialize inicache header */ ZEROMEMORY(Cache, sizeof(INFCACHE)); Cache->LanguageId = LanguageId; /* Parse the inf buffer */ if (!RtlIsTextUnicode(FileBuffer, FileBufferLength, NULL)) { // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf }; WCHAR *new_buff; // UINT codepage = CP_ACP; UINT offset = 0; // if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) )) // { // codepage = CP_UTF8; // offset = sizeof(utf8_bom); // } new_buff = MALLOC(FileBufferLength * sizeof(WCHAR)); if (new_buff != NULL) { ULONG len; Status = RtlMultiByteToUnicodeN(new_buff, FileBufferLength * sizeof(WCHAR), &len, (char *)FileBuffer + offset, FileBufferLength - offset); Status = InfpParseBuffer(Cache, new_buff, new_buff + len / sizeof(WCHAR), ErrorLine); FREE(new_buff); } else Status = INF_STATUS_INSUFFICIENT_RESOURCES; } else { WCHAR *new_buff = (WCHAR *)FileBuffer; /* UCS-16 files should start with the Unicode BOM; we should skip it */ if (*new_buff == 0xfeff) { new_buff++; FileBufferLength -= sizeof(WCHAR); } Status = InfpParseBuffer(Cache, new_buff, (WCHAR*)((char*)new_buff + FileBufferLength), ErrorLine); } if (!INF_SUCCESS(Status)) { FREE(Cache); Cache = NULL; } /* Free file buffer */ FREE(FileBuffer); *InfHandle = (HINF)Cache; return(Status); }
static INT CommandDumpSector( PCONSOLE_STATE State, LPSTR param) { OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING PathName; HANDLE hDisk = NULL; DISK_GEOMETRY DiskGeometry; NTSTATUS Status; LPTSTR *argv = NULL; INT argc = 0; WCHAR DriveName[40]; ULONG ulDrive; // ULONG ulSector; LARGE_INTEGER Sector, SectorCount, Offset; PUCHAR Buffer = NULL; DPRINT1("param: %s\n", param); if (!strcmp(param, "/?")) { HelpDumpSector(); return 0; } argv = split(param, &argc); DPRINT1("argc: %d\n", argc); DPRINT1("argv: %p\n", argv); if (argc != 2) { goto done; } DPRINT1("Device: %s\n", argv[0]); DPRINT1("Sector: %s\n", argv[1]); ulDrive = strtoul(argv[0], NULL, 0); // ulSector = strtoul(argv[1], NULL, 0); Sector.QuadPart = _atoi64(argv[1]); /* Build full drive name */ // swprintf(DriveName, L"\\\\.\\PHYSICALDRIVE%lu", ulDrive); swprintf(DriveName, L"\\Device\\Harddisk%lu\\Partition0", ulDrive); RtlInitUnicodeString(&PathName, DriveName); InitializeObjectAttributes(&ObjectAttributes, &PathName, OBJ_CASE_INSENSITIVE | OBJ_INHERIT, NULL, NULL); Status = NtOpenFile(&hDisk, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateFile failed (Status 0x%08lx)\n", Status); goto done; } Status = NtDeviceIoControlFile(hDisk, NULL, NULL, NULL, &IoStatusBlock, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &DiskGeometry, sizeof(DISK_GEOMETRY)); if (!NT_SUCCESS(Status)) { DPRINT1("NtDeviceIoControlFile failed (Status 0x%08lx)\n", Status); goto done; } DPRINT1("Drive number: %lu\n", ulDrive); DPRINT1("Cylinders: %I64u\nMediaType: %x\nTracksPerCylinder: %lu\n" "SectorsPerTrack: %lu\nBytesPerSector: %lu\n\n", DiskGeometry.Cylinders.QuadPart, DiskGeometry.MediaType, DiskGeometry.TracksPerCylinder, DiskGeometry.SectorsPerTrack, DiskGeometry.BytesPerSector); DPRINT1("Sector: %I64u\n", Sector.QuadPart); SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart * (ULONGLONG)DiskGeometry.TracksPerCylinder * (ULONGLONG)DiskGeometry.SectorsPerTrack; if (Sector.QuadPart >= SectorCount.QuadPart) { CONSOLE_ConOutPrintf("Invalid sector number! Valid range: [0 - %I64u]\n", SectorCount.QuadPart - 1); goto done; } Buffer = RtlAllocateHeap(ProcessHeap, 0, DiskGeometry.BytesPerSector); if (Buffer == NULL) { DPRINT1("Buffer allocation failed\n"); goto done; } Offset.QuadPart = Sector.QuadPart * DiskGeometry.BytesPerSector; DPRINT1("Offset: %I64u\n", Offset.QuadPart); Status = NtReadFile(hDisk, NULL, NULL, NULL, &IoStatusBlock, Buffer, DiskGeometry.BytesPerSector, &Offset, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("NtReadFile failed (Status 0x%08lx)\n", Status); goto done; } HexDump(Buffer, DiskGeometry.BytesPerSector); done: if (Buffer != NULL) RtlFreeHeap(ProcessHeap, 0, Buffer); if (hDisk != NULL) NtClose(hDisk); freep(argv); return 0; }
static NTSTATUS CopyLoop ( HANDLE FileHandleSource, HANDLE FileHandleDest, LARGE_INTEGER SourceFileSize, LPPROGRESS_ROUTINE lpProgressRoutine, LPVOID lpData, BOOL *pbCancel, BOOL *KeepDest ) { NTSTATUS errCode; IO_STATUS_BLOCK IoStatusBlock; UCHAR *lpBuffer = NULL; SIZE_T RegionSize = 0x10000; LARGE_INTEGER BytesCopied; DWORD CallbackReason; DWORD ProgressResult; BOOL EndOfFileFound; *KeepDest = FALSE; errCode = NtAllocateVirtualMemory(NtCurrentProcess(), (PVOID *)&lpBuffer, 2, &RegionSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (NT_SUCCESS(errCode)) { BytesCopied.QuadPart = 0; EndOfFileFound = FALSE; CallbackReason = CALLBACK_STREAM_SWITCH; while (! EndOfFileFound && NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel)) { if (NULL != lpProgressRoutine) { ProgressResult = (*lpProgressRoutine)(SourceFileSize, BytesCopied, SourceFileSize, BytesCopied, 0, CallbackReason, FileHandleSource, FileHandleDest, lpData); switch (ProgressResult) { case PROGRESS_CANCEL: TRACE("Progress callback requested cancel\n"); errCode = STATUS_REQUEST_ABORTED; break; case PROGRESS_STOP: TRACE("Progress callback requested stop\n"); errCode = STATUS_REQUEST_ABORTED; *KeepDest = TRUE; break; case PROGRESS_QUIET: lpProgressRoutine = NULL; break; case PROGRESS_CONTINUE: default: break; } CallbackReason = CALLBACK_CHUNK_FINISHED; } if (NT_SUCCESS(errCode)) { errCode = NtReadFile(FileHandleSource, NULL, NULL, NULL, (PIO_STATUS_BLOCK)&IoStatusBlock, lpBuffer, RegionSize, NULL, NULL); if (NT_SUCCESS(errCode) && (NULL == pbCancel || ! *pbCancel)) { errCode = NtWriteFile(FileHandleDest, NULL, NULL, NULL, (PIO_STATUS_BLOCK)&IoStatusBlock, lpBuffer, IoStatusBlock.Information, NULL, NULL); if (NT_SUCCESS(errCode)) { BytesCopied.QuadPart += IoStatusBlock.Information; } else { WARN("Error 0x%08x reading writing to dest\n", errCode); } } else if (!NT_SUCCESS(errCode)) { if (STATUS_END_OF_FILE == errCode) { EndOfFileFound = TRUE; errCode = STATUS_SUCCESS; } else { WARN("Error 0x%08x reading from source\n", errCode); } } } } if (! EndOfFileFound && (NULL != pbCancel && *pbCancel)) { TRACE("User requested cancel\n"); errCode = STATUS_REQUEST_ABORTED; } NtFreeVirtualMemory(NtCurrentProcess(), (PVOID *)&lpBuffer, &RegionSize, MEM_RELEASE); } else { TRACE("Error 0x%08x allocating buffer of %d bytes\n", errCode, RegionSize); } return errCode; }
/* * @implemented */ BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL) { NTSTATUS Status; TRACE("ReadFile(hFile %p)\n", hFile); if (lpNumberOfBytesRead != NULL) *lpNumberOfBytesRead = 0; if (!nNumberOfBytesToRead) return TRUE; hFile = TranslateStdHandle(hFile); if (IsConsoleHandle(hFile)) { if (ReadConsoleA(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL)) { DWORD dwMode; GetConsoleMode(hFile, &dwMode); if ((dwMode & ENABLE_PROCESSED_INPUT) && *(PCHAR)lpBuffer == 0x1a) { /* EOF character entered; simulate end-of-file */ *lpNumberOfBytesRead = 0; } return TRUE; } return FALSE; } if (lpOverlapped != NULL) { LARGE_INTEGER Offset; PVOID ApcContext; Offset.u.LowPart = lpOverlapped->Offset; Offset.u.HighPart = lpOverlapped->OffsetHigh; lpOverlapped->Internal = STATUS_PENDING; ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped); Status = NtReadFile(hFile, lpOverlapped->hEvent, NULL, ApcContext, (PIO_STATUS_BLOCK)lpOverlapped, lpBuffer, nNumberOfBytesToRead, &Offset, NULL); /* return FALSE in case of failure and pending operations! */ if (!NT_SUCCESS(Status) || Status == STATUS_PENDING) { if (Status == STATUS_END_OF_FILE && lpNumberOfBytesRead != NULL) *lpNumberOfBytesRead = 0; BaseSetLastNTError(Status); return FALSE; } if (lpNumberOfBytesRead != NULL) *lpNumberOfBytesRead = lpOverlapped->InternalHigh; } else { IO_STATUS_BLOCK Iosb; Status = NtReadFile(hFile, NULL, NULL, NULL, &Iosb, lpBuffer, nNumberOfBytesToRead, NULL, NULL); /* Wait in case operation is pending */ if (Status == STATUS_PENDING) { Status = NtWaitForSingleObject(hFile, FALSE, NULL); if (NT_SUCCESS(Status)) Status = Iosb.Status; } 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). */ *lpNumberOfBytesRead = 0; return TRUE; } if (NT_SUCCESS(Status)) { /* * lpNumberOfBytesRead must not be NULL here, in fact Win doesn't * check that case either and crashes (only after the operation * completed). */ *lpNumberOfBytesRead = Iosb.Information; } else { BaseSetLastNTError(Status); return FALSE; } } TRACE("ReadFile() succeeded\n"); return TRUE; }
static void find_devices(HWND hwnd, const GUID* guid, const nt_handle& mountmgr, vector<device>& device_list) { HDEVINFO h; static WCHAR dosdevices[] = L"\\DosDevices\\"; h = SetupDiGetClassDevs(guid, nullptr, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (h != INVALID_HANDLE_VALUE) { DWORD index = 0; SP_DEVICE_INTERFACE_DATA did; did.cbSize = sizeof(did); if (!SetupDiEnumDeviceInterfaces(h, nullptr, guid, index, &did)) return; do { SP_DEVINFO_DATA dd; SP_DEVICE_INTERFACE_DETAIL_DATA_W* detail; DWORD size; dd.cbSize = sizeof(dd); SetupDiGetDeviceInterfaceDetailW(h, &did, nullptr, 0, &size, nullptr); detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)malloc(size); memset(detail, 0, size); detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); if (SetupDiGetDeviceInterfaceDetailW(h, &did, detail, size, &size, &dd)) { NTSTATUS Status; nt_handle file; device dev; STORAGE_DEVICE_NUMBER sdn; IO_STATUS_BLOCK iosb; UNICODE_STRING path; OBJECT_ATTRIBUTES attr; GET_LENGTH_INFORMATION gli; ULONG i; uint8_t sb[4096]; path.Buffer = detail->DevicePath; path.Length = path.MaximumLength = (uint16_t)(wcslen(detail->DevicePath) * sizeof(WCHAR)); if (path.Length > 4 * sizeof(WCHAR) && path.Buffer[0] == '\\' && path.Buffer[1] == '\\' && path.Buffer[2] == '?' && path.Buffer[3] == '\\') path.Buffer[1] = '?'; InitializeObjectAttributes(&attr, &path, 0, nullptr, nullptr); Status = NtOpenFile(&file, FILE_GENERIC_READ, &attr, &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_ALERT); if (!NT_SUCCESS(Status)) { free(detail); index++; continue; } dev.pnp_name = detail->DevicePath; Status = NtDeviceIoControlFile(file, nullptr, nullptr, nullptr, &iosb, IOCTL_DISK_GET_LENGTH_INFO, nullptr, 0, &gli, sizeof(GET_LENGTH_INFORMATION)); if (!NT_SUCCESS(Status)) { free(detail); index++; continue; } dev.size = gli.Length.QuadPart; Status = NtDeviceIoControlFile(file, nullptr, nullptr, nullptr, &iosb, IOCTL_STORAGE_GET_DEVICE_NUMBER, nullptr, 0, &sdn, sizeof(STORAGE_DEVICE_NUMBER)); if (!NT_SUCCESS(Status)) { dev.disk_num = 0xffffffff; dev.part_num = 0xffffffff; } else { dev.disk_num = sdn.DeviceNumber; dev.part_num = sdn.PartitionNumber; } dev.friendly_name = L""; dev.drive = L""; dev.fstype = L""; dev.has_parts = false; dev.ignore = false; dev.multi_device = false; dev.is_disk = RtlCompareMemory(guid, &GUID_DEVINTERFACE_DISK, sizeof(GUID)) == sizeof(GUID); if (dev.is_disk) { STORAGE_PROPERTY_QUERY spq; STORAGE_DEVICE_DESCRIPTOR sdd, *sdd2; ULONG dlisize; DRIVE_LAYOUT_INFORMATION_EX* dli; spq.PropertyId = StorageDeviceProperty; spq.QueryType = PropertyStandardQuery; spq.AdditionalParameters[0] = 0; Status = NtDeviceIoControlFile(file, nullptr, nullptr, nullptr, &iosb, IOCTL_STORAGE_QUERY_PROPERTY, &spq, sizeof(STORAGE_PROPERTY_QUERY), &sdd, sizeof(STORAGE_DEVICE_DESCRIPTOR)); if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) { sdd2 = (STORAGE_DEVICE_DESCRIPTOR*)malloc(sdd.Size); Status = NtDeviceIoControlFile(file, nullptr, nullptr, nullptr, &iosb, IOCTL_STORAGE_QUERY_PROPERTY, &spq, sizeof(STORAGE_PROPERTY_QUERY), sdd2, sdd.Size); if (NT_SUCCESS(Status)) { string desc2; desc2 = ""; if (sdd2->VendorIdOffset != 0) { desc2 += (char*)((uint8_t*)sdd2 + sdd2->VendorIdOffset); while (desc2.length() > 0 && desc2[desc2.length() - 1] == ' ') desc2 = desc2.substr(0, desc2.length() - 1); } if (sdd2->ProductIdOffset != 0) { if (sdd2->VendorIdOffset != 0 && desc2.length() != 0 && desc2[desc2.length() - 1] != ' ') desc2 += " "; desc2 += (char*)((uint8_t*)sdd2 + sdd2->ProductIdOffset); while (desc2.length() > 0 && desc2[desc2.length() - 1] == ' ') desc2 = desc2.substr(0, desc2.length() - 1); } if (sdd2->VendorIdOffset != 0 || sdd2->ProductIdOffset != 0) { ULONG ss; ss = MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, desc2.c_str(), -1, nullptr, 0); if (ss > 0) { WCHAR* desc3 = (WCHAR*)malloc(ss * sizeof(WCHAR)); if (MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, desc2.c_str(), -1, desc3, ss * sizeof(WCHAR))) dev.friendly_name = desc3; free(desc3); } } } free(sdd2); } dlisize = 0; dli = nullptr; do { dlisize += 1024; if (dli) free(dli); dli = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(dlisize); Status = NtDeviceIoControlFile(file, nullptr, nullptr, nullptr, &iosb, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nullptr, 0, dli, dlisize); } while (Status == STATUS_BUFFER_TOO_SMALL); if (NT_SUCCESS(Status) && dli->PartitionCount > 0) dev.has_parts = true; free(dli); } else { ULONG mmpsize; MOUNTMGR_MOUNT_POINT* mmp; MOUNTMGR_MOUNT_POINTS mmps; mmpsize = sizeof(MOUNTMGR_MOUNT_POINT) + path.Length; mmp = (MOUNTMGR_MOUNT_POINT*)malloc(mmpsize); RtlZeroMemory(mmp, sizeof(MOUNTMGR_MOUNT_POINT)); mmp->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT); mmp->DeviceNameLength = path.Length; RtlCopyMemory(&mmp[1], path.Buffer, path.Length); Status = NtDeviceIoControlFile(mountmgr, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTMGR_QUERY_POINTS, mmp, mmpsize, &mmps, sizeof(MOUNTMGR_MOUNT_POINTS)); if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) { MOUNTMGR_MOUNT_POINTS* mmps2; mmps2 = (MOUNTMGR_MOUNT_POINTS*)malloc(mmps.Size); Status = NtDeviceIoControlFile(mountmgr, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTMGR_QUERY_POINTS, mmp, mmpsize, mmps2, mmps.Size); if (NT_SUCCESS(Status)) { ULONG i; for (i = 0; i < mmps2->NumberOfMountPoints; i++) { WCHAR* symlink = (WCHAR*)((uint8_t*)mmps2 + mmps2->MountPoints[i].SymbolicLinkNameOffset); if (mmps2->MountPoints[i].SymbolicLinkNameLength == 0x1c && RtlCompareMemory(symlink, dosdevices, wcslen(dosdevices) * sizeof(WCHAR)) == wcslen(dosdevices) * sizeof(WCHAR) && symlink[13] == ':' ) { WCHAR dr[3]; dr[0] = symlink[12]; dr[1] = ':'; dr[2] = 0; dev.drive = dr; break; } } } } free(mmp); } if (!dev.is_disk || !dev.has_parts) { i = 0; while (fs_ident[i].name) { if (i == 0 || fs_ident[i].kboff != fs_ident[i-1].kboff) { LARGE_INTEGER off; off.QuadPart = fs_ident[i].kboff * 1024; Status = NtReadFile(file, nullptr, nullptr, nullptr, &iosb, sb, sizeof(sb), &off, nullptr); } if (NT_SUCCESS(Status)) { if (RtlCompareMemory(sb + fs_ident[i].sboff, fs_ident[i].magic, fs_ident[i].magiclen) == fs_ident[i].magiclen) { dev.fstype = fs_ident[i].name; if (dev.fstype == L"Btrfs") { superblock* bsb = (superblock*)sb; RtlCopyMemory(&dev.fs_uuid, &bsb->uuid, sizeof(BTRFS_UUID)); RtlCopyMemory(&dev.dev_uuid, &bsb->dev_item.device_uuid, sizeof(BTRFS_UUID)); } break; } } i++; } if (dev.fstype == L"Btrfs" && RtlCompareMemory(guid, &GUID_DEVINTERFACE_DISK, sizeof(GUID)) != sizeof(GUID)) { wstring name; wstring pref = L"\\Device\\Btrfs{"; name = get_mountdev_name(file); if (name.length() > pref.length() && RtlCompareMemory(name.c_str(), pref.c_str(), pref.length() * sizeof(WCHAR)) == pref.length() * sizeof(WCHAR)) dev.ignore = true; } } device_list.push_back(dev); } free(detail); index++; } while (SetupDiEnumDeviceInterfaces(h, nullptr, guid, index, &did)); SetupDiDestroyDeviceInfoList(h); } else throw last_error(GetLastError()); }
NTSTATUS IniCacheLoad( PINICACHE *Cache, PWCHAR FileName, BOOLEAN String) { UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; FILE_STANDARD_INFORMATION FileInfo; IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; NTSTATUS Status; PCHAR FileBuffer; ULONG FileLength; PCHAR Ptr; LARGE_INTEGER FileOffset; PINICACHESECTION Section; PINICACHEKEY Key; PCHAR SectionName; ULONG SectionNameSize; PCHAR KeyName; ULONG KeyNameSize; PCHAR KeyValue; ULONG KeyValueSize; *Cache = NULL; /* Open ini file */ RtlInitUnicodeString(&Name, FileName); InitializeObjectAttributes(&ObjectAttributes, &Name, 0, NULL, NULL); Status = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenFile() failed (Status %lx)\n", Status); return Status; } DPRINT("NtOpenFile() successful\n"); /* Query file size */ Status = NtQueryInformationFile(FileHandle, &IoStatusBlock, &FileInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!NT_SUCCESS(Status)) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return Status; } FileLength = FileInfo.EndOfFile.u.LowPart; DPRINT("File size: %lu\n", FileLength); /* Allocate file buffer */ FileBuffer = (CHAR*)RtlAllocateHeap(ProcessHeap, 0, FileLength + 1); if (FileBuffer == NULL) { DPRINT1("RtlAllocateHeap() failed\n"); NtClose(FileHandle); return STATUS_INSUFFICIENT_RESOURCES; } /* Read file */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, FileBuffer, FileLength, &FileOffset, NULL); /* Append string terminator */ FileBuffer[FileLength] = 0; NtClose(FileHandle); if (!NT_SUCCESS(Status)) { DPRINT("NtReadFile() failed (Status %lx)\n", Status); RtlFreeHeap(ProcessHeap, 0, FileBuffer); return Status; } /* Allocate inicache header */ *Cache = (PINICACHE)RtlAllocateHeap(ProcessHeap, 0, sizeof(INICACHE)); if (*Cache == NULL) { DPRINT("RtlAllocateHeap() failed\n"); return STATUS_INSUFFICIENT_RESOURCES; } /* Initialize inicache header */ RtlZeroMemory(*Cache, sizeof(INICACHE)); /* Parse ini file */ Section = NULL; Ptr = FileBuffer; while (Ptr != NULL && *Ptr != 0) { Ptr = IniCacheSkipWhitespace(Ptr); if (Ptr == NULL) continue; if (*Ptr == '[') { Section = NULL; Ptr++; Ptr = IniCacheGetSectionName(Ptr, &SectionName, &SectionNameSize); DPRINT1("[%.*s]\n", SectionNameSize, SectionName); Section = IniCacheAddSection(*Cache, SectionName, SectionNameSize); if (Section == NULL) { DPRINT("IniCacheAddSection() failed\n"); Ptr = IniCacheSkipToNextSection(Ptr); continue; } } else { if (Section == NULL) { Ptr = IniCacheSkipToNextSection(Ptr); continue; } Ptr = IniCacheGetKeyName(Ptr, &KeyName, &KeyNameSize); Ptr = IniCacheGetKeyValue(Ptr, &KeyValue, &KeyValueSize, String); DPRINT1("'%.*s' = '%.*s'\n", KeyNameSize, KeyName, KeyValueSize, KeyValue); Key = IniCacheAddKey(Section, KeyName, KeyNameSize, KeyValue, KeyValueSize); if (Key == NULL) { DPRINT("IniCacheAddKey() failed\n"); } } } /* Free file buffer */ RtlFreeHeap(ProcessHeap, 0, FileBuffer); return Status; }
/* * @unimplemented */ BOOL WINAPI ReplaceFileW( LPCWSTR lpReplacedFileName, LPCWSTR lpReplacementFileName, LPCWSTR lpBackupFileName, DWORD dwReplaceFlags, LPVOID lpExclude, LPVOID lpReserved ) { HANDLE hReplaced = NULL, hReplacement = NULL; UNICODE_STRING NtReplacedName = { 0, 0, NULL }; UNICODE_STRING NtReplacementName = { 0, 0, NULL }; DWORD Error = ERROR_SUCCESS; NTSTATUS Status; BOOL Ret = FALSE; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; PVOID Buffer = NULL ; if (dwReplaceFlags) FIXME("Ignoring flags %x\n", dwReplaceFlags); /* First two arguments are mandatory */ if (!lpReplacedFileName || !lpReplacementFileName) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } /* Back it up */ if(lpBackupFileName) { if(!CopyFileW(lpReplacedFileName, lpBackupFileName, FALSE)) { Error = GetLastError(); goto Cleanup ; } } /* Open the "replaced" file for reading and writing */ if (!(RtlDosPathNameToNtPathName_U(lpReplacedFileName, &NtReplacedName, NULL, NULL))) { Error = ERROR_PATH_NOT_FOUND; goto Cleanup; } InitializeObjectAttributes(&ObjectAttributes, &NtReplacedName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenFile(&hReplaced, GENERIC_READ | GENERIC_WRITE | DELETE | SYNCHRONIZE | WRITE_DAC, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (!NT_SUCCESS(Status)) { if (Status == STATUS_OBJECT_NAME_NOT_FOUND) Error = ERROR_FILE_NOT_FOUND; else Error = ERROR_UNABLE_TO_REMOVE_REPLACED; goto Cleanup; } /* Blank it */ SetEndOfFile(hReplaced) ; /* * Open the replacement file for reading, writing, and deleting * (deleting is needed when finished) */ if (!(RtlDosPathNameToNtPathName_U(lpReplacementFileName, &NtReplacementName, NULL, NULL))) { Error = ERROR_PATH_NOT_FOUND; goto Cleanup; } InitializeObjectAttributes(&ObjectAttributes, &NtReplacementName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenFile(&hReplacement, GENERIC_READ | DELETE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, 0, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE); if (!NT_SUCCESS(Status)) { Error = RtlNtStatusToDosError(Status); goto Cleanup; } Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 0x10000) ; if (!Buffer) { Error = ERROR_NOT_ENOUGH_MEMORY; goto Cleanup ; } while (Status != STATUS_END_OF_FILE) { Status = NtReadFile(hReplacement, NULL, NULL, NULL, &IoStatusBlock, Buffer, 0x10000, NULL, NULL) ; if (NT_SUCCESS(Status)) { Status = NtWriteFile(hReplaced, NULL, NULL, NULL, &IoStatusBlock, Buffer, IoStatusBlock.Information, NULL, NULL) ; if (!NT_SUCCESS(Status)) { Error = RtlNtStatusToDosError(Status); goto Cleanup; } } else if (Status != STATUS_END_OF_FILE) { Error = RtlNtStatusToDosError(Status); goto Cleanup; } } Ret = TRUE; /* Perform resource cleanup */ Cleanup: if (hReplaced) NtClose(hReplaced); if (hReplacement) NtClose(hReplacement); if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); if (NtReplacementName.Buffer) RtlFreeHeap(GetProcessHeap(), 0, NtReplacementName.Buffer); if (NtReplacedName.Buffer) RtlFreeHeap(GetProcessHeap(), 0, NtReplacedName.Buffer); /* If there was an error, set the error code */ if(!Ret) { TRACE("ReplaceFileW failed (error=%lu)\n", Error); SetLastError(Error); } return Ret; }
/*++ * @name SmpMoveFile * * The SmpMoveFile function deletes a specify file. * * @param lpExistingFileName * the name of an existing file which should be removed * * @param lpNewFileName * a new name of an existing file. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL * othwerwise. * * @remarks * This function called from the SmpMoveFilesQueryRoutine function. * * *--*/ NTSTATUS SmpMoveFile( IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName ) { PFILE_RENAME_INFORMATION FileRenameInfo; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING ExistingFileNameU; HANDLE FileHandle; DWORD FileNameSize; BOOLEAN ReplaceIfExists; NTSTATUS Status; if( !lpExistingFileName || !lpNewFileName ) return (STATUS_INVALID_PARAMETER); DPRINT("SmpMoveFile (%S, %S)\n", lpExistingFileName, lpNewFileName); RtlInitUnicodeString(&ExistingFileNameU, lpExistingFileName); InitializeObjectAttributes(&ObjectAttributes, &ExistingFileNameU, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateFile (&FileHandle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if( !NT_SUCCESS(Status) ) { DPRINT("NtCreateFile() failed (Status %lx)\n", Status); return (Status); } FileNameSize = wcslen(lpNewFileName)*sizeof(*lpNewFileName); FileRenameInfo = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FILE_RENAME_INFORMATION)+FileNameSize); if( !FileRenameInfo ) { DPRINT("RtlAllocateHeap failed\n"); NtClose(FileHandle); return (STATUS_NO_MEMORY); } if( L'!' == *lpNewFileName ) { lpNewFileName++; FileNameSize -= sizeof(*lpNewFileName); ReplaceIfExists = TRUE; } else { ReplaceIfExists = FALSE; } FileRenameInfo->RootDirectory = NULL; FileRenameInfo->ReplaceIfExists = ReplaceIfExists; FileRenameInfo->FileNameLength = FileNameSize; RtlCopyMemory(FileRenameInfo->FileName, lpNewFileName, FileNameSize); Status = NtSetInformationFile( FileHandle, &IoStatusBlock, FileRenameInfo, sizeof(FILE_RENAME_INFORMATION)+FileNameSize, FileRenameInformation ); RtlFreeHeap(RtlGetProcessHeap(), 0, FileRenameInfo); /* FIXME: After the FileRenameInformation parameter will be implemented into the fs driver the following code can be removed */ if( STATUS_NOT_IMPLEMENTED == Status ) { HANDLE FileHandleNew; UNICODE_STRING NewFileNameU; FILE_BASIC_INFORMATION FileBasicInfo; UCHAR *lpBuffer = NULL; SIZE_T RegionSize = 0x10000; LARGE_INTEGER BytesCopied; BOOL EndOfFileFound; Status = NtQueryInformationFile( FileHandle, &IoStatusBlock, &FileBasicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if( !NT_SUCCESS(Status) ) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return (Status); } RtlInitUnicodeString(&NewFileNameU, lpNewFileName); InitializeObjectAttributes(&ObjectAttributes, &NewFileNameU, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateFile (&FileHandleNew, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, ReplaceIfExists ? FILE_OVERWRITE_IF : FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if( !NT_SUCCESS(Status) ) { DPRINT("NtCreateFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return (Status); } Status = NtAllocateVirtualMemory( NtCurrentProcess(), (PVOID *)&lpBuffer, 2, &RegionSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if( !NT_SUCCESS(Status) ) { DPRINT("NtAllocateVirtualMemory() failed (Status %lx)\n", Status); NtClose(FileHandle); SmpDeleteFile(lpNewFileName); return (Status); } BytesCopied.QuadPart = 0; EndOfFileFound = FALSE; while( !EndOfFileFound && NT_SUCCESS(Status) ) { Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, lpBuffer, RegionSize, NULL, NULL); if( NT_SUCCESS(Status) ) { Status = NtWriteFile(FileHandleNew, NULL, NULL, NULL, &IoStatusBlock, lpBuffer, IoStatusBlock.Information, NULL, NULL); if( NT_SUCCESS(Status) ) { BytesCopied.QuadPart += IoStatusBlock.Information; } else { DPRINT("NtWriteFile() failed (Status %lx)\n", Status); } } else { if( STATUS_END_OF_FILE == Status ) { EndOfFileFound = TRUE; Status = STATUS_SUCCESS; } else { DPRINT("NtWriteFile() failed (Status %lx)\n", Status); } } } NtFreeVirtualMemory(NtCurrentProcess(), (PVOID *)&lpBuffer, &RegionSize, MEM_RELEASE); Status = NtQueryInformationFile( FileHandleNew, &IoStatusBlock, &FileBasicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if( !NT_SUCCESS(Status) ) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); } Status = NtSetInformationFile(FileHandleNew, &IoStatusBlock, &FileBasicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if( !NT_SUCCESS(Status) ) { DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status); } NtClose(FileHandleNew); NtClose(FileHandle); SmpDeleteFile(lpExistingFileName); return (Status); } NtClose(FileHandle); return (Status); }
VOID Read( IN PCHAR FileName, IN ULONG FileTime, IN ULONG FileCount ) { NTSTATUS Status; HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; IO_STATUS_BLOCK IoStatus; LARGE_INTEGER AllocationSize; LARGE_INTEGER ByteOffset; ULONG Count; ULONG Pattern[3]; // // Get the filename // simprintf("Read ", 0); simprintf(FileName, 0); simprintf("\n", 0); // // Open the existing file // AllocationSize = LiFromUlong( FileCount * 4 ); RtlInitString( &NameString, FileName ); InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL ); if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle, FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatus, 0L, WriteThrough ))) { OpenFileError( Status, FileName ); return; } // // The main loop read in the test pattern our test pattern // is <FileTime> <FileSize> <Count> where count is the current // iteration count for the current test pattern output. // for (Count = 0; Count < FileCount; Count += 1) { ByteOffset = LiFromUlong( Count * 3 * 4 ); if (!NT_SUCCESS(Status = NtReadFile( FileHandle, (HANDLE)NULL, (PIO_APC_ROUTINE)NULL, (PVOID)NULL, &IoStatus, Pattern, 3 * 4, &ByteOffset, (PULONG) NULL ))) { ReadFileError( Status ); return; } if (!NT_SUCCESS(Status = NtWaitForSingleObject(FileHandle, TRUE, NULL))) { WaitForSingleObjectError( Status ); return; } // // check how the read turned out // CheckIoStatus( &IoStatus, 3 * 4, TRUE ); if (!NT_SUCCESS(IoStatus.Status)) { IoStatusError( IoStatus.Status ); break; } // // Now compare the what we read with what we should have read // if ((Pattern[0] != FileTime) || (Pattern[1] != FileCount) || (Pattern[2] != Count)) { printf("**** Read Error ****\n"); NtPartyByNumber( 50 ); return; } } // // Now close the file // if (!NT_SUCCESS(Status = NtClose( FileHandle ))) { CloseError( Status ); } // // And return to our caller // return; }
NTSTATUS InfOpenFile(PHINF InfHandle, PUNICODE_STRING FileName, PULONG ErrorLine) { OBJECT_ATTRIBUTES ObjectAttributes; FILE_STANDARD_INFORMATION FileInfo; IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; NTSTATUS Status; PCHAR FileBuffer; ULONG FileLength; LARGE_INTEGER FileOffset; PINFCACHE Cache; CheckHeap(); *InfHandle = NULL; *ErrorLine = (ULONG)-1; /* Open the inf file */ InitializeObjectAttributes(&ObjectAttributes, FileName, 0, NULL, NULL); Status = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (!INF_SUCCESS(Status)) { DPRINT("NtOpenFile() failed (Status %lx)\n", Status); return(Status); } DPRINT("NtOpenFile() successful\n"); /* Query file size */ Status = NtQueryInformationFile(FileHandle, &IoStatusBlock, &FileInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!INF_SUCCESS(Status)) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return(Status); } FileLength = FileInfo.EndOfFile.u.LowPart; DPRINT("File size: %lu\n", FileLength); /* Allocate file buffer */ FileBuffer = MALLOC(FileLength + 1); if (FileBuffer == NULL) { DPRINT1("MALLOC() failed\n"); NtClose(FileHandle); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Read file */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, FileBuffer, FileLength, &FileOffset, NULL); /* Append string terminator */ FileBuffer[FileLength] = 0; NtClose(FileHandle); if (!INF_SUCCESS(Status)) { DPRINT("NtReadFile() failed (Status %lx)\n", Status); FREE(FileBuffer); return(Status); } /* Allocate infcache header */ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); if (Cache == NULL) { DPRINT("MALLOC() failed\n"); FREE(FileBuffer); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Initialize inicache header */ ZEROMEMORY(Cache, sizeof(INFCACHE)); /* Parse the inf buffer */ Status = InfpParseBuffer (Cache, FileBuffer, FileBuffer + FileLength, ErrorLine); if (!INF_SUCCESS(Status)) { FREE(Cache); Cache = NULL; } /* Free file buffer */ FREE(FileBuffer); *InfHandle = (HINF)Cache; return(Status); }
int __cdecl main(int argc, char *argv[]) { static PH_COMMAND_LINE_OPTION options[] = { { FI_ARG_HELP, L"h", NoArgumentType }, { FI_ARG_ACTION, L"a", MandatoryArgumentType }, { FI_ARG_NATIVE, L"N", NoArgumentType }, { FI_ARG_PATTERN, L"p", MandatoryArgumentType }, { FI_ARG_CASESENSITIVE, L"C", NoArgumentType }, { FI_ARG_OUTPUT, L"o", MandatoryArgumentType }, { FI_ARG_FORCE, L"f", NoArgumentType }, { FI_ARG_LENGTH, L"L", MandatoryArgumentType } }; PH_STRINGREF commandLine; NTSTATUS status = STATUS_SUCCESS; if (!NT_SUCCESS(PhInitializePhLibEx(0, 0, 0))) return 1; PhUnicodeStringToStringRef(&NtCurrentPeb()->ProcessParameters->CommandLine, &commandLine); if (!PhParseCommandLine( &commandLine, options, sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION), PH_COMMAND_LINE_IGNORE_FIRST_PART, FiCommandLineCallback, NULL ) || FiArgHelp) { FiPrintHelp(); return 0; } if (!FiArgFileName && ( FiArgAction && PhEqualString2(FiArgAction, L"dir", TRUE) )) { FiArgFileName = PhCreateStringFromUnicodeString(&NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath); } if (!FiArgAction) { FiPrintHelp(); return 1; } else if (PhEqualString2(FiArgAction, L"map", TRUE)) { WCHAR deviceNameBuffer[7] = L"\\??\\ :"; ULONG i; WCHAR targetNameBuffer[0x100]; UNICODE_STRING targetName; targetName.Buffer = targetNameBuffer; targetName.MaximumLength = sizeof(targetNameBuffer); for (i = 0; i < 26; i++) { HANDLE linkHandle; OBJECT_ATTRIBUTES oa; UNICODE_STRING deviceName; deviceNameBuffer[4] = (WCHAR)('A' + i); deviceName.Buffer = deviceNameBuffer; deviceName.Length = 6 * sizeof(WCHAR); InitializeObjectAttributes( &oa, &deviceName, OBJ_CASE_INSENSITIVE, NULL, NULL ); if (NT_SUCCESS(NtOpenSymbolicLinkObject( &linkHandle, SYMBOLIC_LINK_QUERY, &oa ))) { if (NT_SUCCESS(NtQuerySymbolicLinkObject( linkHandle, &targetName, NULL ))) { wprintf(L"%c: %.*s\n", 'A' + i, targetName.Length / 2, targetName.Buffer); } NtClose(linkHandle); } } } else if (!FiArgFileName) { wprintf(L"Error: file name missing.\n"); FiPrintHelp(); return 1; } else if (PhEqualString2(FiArgAction, L"hash", TRUE)) { HANDLE fileHandle; LARGE_INTEGER fileSize; IO_STATUS_BLOCK isb; ULONG mode; if (!FiArgOutput) mode = HASH_MD5; else if (PhEqualString2(FiArgOutput, L"md5", TRUE)) mode = HASH_MD5; else if (PhEqualString2(FiArgOutput, L"sha1", TRUE)) mode = HASH_SHA1; else if (PhEqualString2(FiArgOutput, L"crc32", TRUE)) mode = HASH_CRC32; else { wprintf(L"Invalid hash algorithm. Possibilities: md5, sha1, crc32\n"); return 1; } if (FiCreateFile( &fileHandle, FILE_GENERIC_READ, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY )) { if (NT_SUCCESS(status = PhGetFileSize(fileHandle, &fileSize))) { MD5_CTX md5Context; A_SHA_CTX shaContext; ULONG crc; UCHAR buffer[PAGE_SIZE * 4]; ULONG64 bytesRemaining; bytesRemaining = fileSize.QuadPart; switch (mode) { case HASH_MD5: MD5Init(&md5Context); break; case HASH_SHA1: A_SHAInit(&shaContext); break; case HASH_CRC32: crc = 0; break; } while (bytesRemaining) { status = NtReadFile( fileHandle, NULL, NULL, NULL, &isb, buffer, sizeof(buffer), NULL, NULL ); if (!NT_SUCCESS(status)) break; switch (mode) { case HASH_MD5: MD5Update(&md5Context, buffer, (ULONG)isb.Information); break; case HASH_SHA1: A_SHAUpdate(&shaContext, buffer, (ULONG)isb.Information); break; case HASH_CRC32: crc = PhCrc32(crc, buffer, isb.Information); break; } bytesRemaining -= (ULONG)isb.Information; } if (status == STATUS_END_OF_FILE) status = STATUS_SUCCESS; switch (mode) { case HASH_MD5: { MD5Final(&md5Context); wprintf(L"%s", PhBufferToHexString(md5Context.digest, 16)->Buffer); } break; case HASH_SHA1: { UCHAR hash[20]; A_SHAFinal(&shaContext, hash); wprintf(L"%s", PhBufferToHexString(hash, 20)->Buffer); } break; case HASH_CRC32: { wprintf(L"%08x", crc); } break; } if (!NT_SUCCESS(status)) wprintf(L"Warning: I/O error encountered: %s\n", PhGetNtMessage(status)->Buffer); } NtClose(fileHandle); } if (!NT_SUCCESS(status)) { wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer); return 1; } } else if (PhEqualString2(FiArgAction, L"execute", TRUE)) { if (FiArgNative) { if (!NT_SUCCESS(status = PhCreateProcess( FiFormatFileName(FiArgFileName)->Buffer, FiArgOutput ? &FiArgOutput->sr : NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL ))) { wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer); return 1; } } else { if (!NT_SUCCESS(status = PhCreateProcessWin32( FiArgFileName->Buffer, PhGetString(FiArgOutput), NULL, NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath.Buffer, PH_CREATE_PROCESS_NEW_CONSOLE, NULL, NULL, NULL ))) { wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer); return 1; } } } else if (PhEqualString2(FiArgAction, L"del", TRUE)) { HANDLE fileHandle; if (FiCreateFile( &fileHandle, DELETE | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT )) { FILE_DISPOSITION_INFORMATION dispositionInfo; IO_STATUS_BLOCK isb; dispositionInfo.DeleteFile = TRUE; if (!NT_SUCCESS(status = NtSetInformationFile(fileHandle, &isb, &dispositionInfo, sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation))) { wprintf(L"Error deleting file: %s\n", PhGetNtMessage(status)->Buffer); } NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"touch", TRUE)) { HANDLE fileHandle; if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"mkdir", TRUE)) { HANDLE fileHandle; if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FiArgFileName, FILE_ATTRIBUTE_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"rename", TRUE)) { HANDLE fileHandle; PPH_STRING newFileName; if (!FiArgOutput) { wprintf(L"Error: new file name missing.\n"); FiPrintHelp(); return 1; } newFileName = FiFormatFileName(FiArgOutput); if (FiCreateFile( &fileHandle, DELETE | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { PFILE_RENAME_INFORMATION renameInfo; ULONG renameInfoSize; IO_STATUS_BLOCK isb; renameInfoSize = FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName) + (ULONG)newFileName->Length; renameInfo = PhAllocate(renameInfoSize); renameInfo->ReplaceIfExists = FiArgForce; renameInfo->RootDirectory = NULL; renameInfo->FileNameLength = (ULONG)newFileName->Length; memcpy(renameInfo->FileName, newFileName->Buffer, newFileName->Length); status = NtSetInformationFile(fileHandle, &isb, renameInfo, renameInfoSize, FileRenameInformation); PhFree(renameInfo); if (!NT_SUCCESS(status)) { wprintf(L"Error renaming file: %s\n", PhGetNtMessage(status)->Buffer); } NtClose(fileHandle); } } else if (PhEqualString2(FiArgAction, L"copy", TRUE)) { HANDLE fileHandle; HANDLE outFileHandle; LARGE_INTEGER fileSize; FILE_BASIC_INFORMATION basicInfo; if (!FiArgOutput) { wprintf(L"Error: output file name missing.\n"); FiPrintHelp(); return 1; } if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | FILE_READ_DATA | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT ) && FiCreateFile( &outFileHandle, FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA | SYNCHRONIZE, FiArgOutput, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, !FiArgForce ? FILE_CREATE : FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT )) { #define COPY_BUFFER_SIZE 0x10000 IO_STATUS_BLOCK isb; PVOID buffer; ULONG64 bytesToCopy = FiArgLength; if (NT_SUCCESS(PhGetFileSize(fileHandle, &fileSize))) { PhSetFileSize(outFileHandle, &fileSize); } buffer = PhAllocatePage(COPY_BUFFER_SIZE, NULL); if (!buffer) { wprintf(L"Error allocating buffer.\n"); return 1; } while (bytesToCopy) { status = NtReadFile( fileHandle, NULL, NULL, NULL, &isb, buffer, bytesToCopy >= COPY_BUFFER_SIZE ? COPY_BUFFER_SIZE : (ULONG)bytesToCopy, NULL, NULL ); if (status == STATUS_END_OF_FILE) { break; } else if (!NT_SUCCESS(status)) { wprintf(L"Error reading from file: %s\n", PhGetNtMessage(status)->Buffer); break; } status = NtWriteFile( outFileHandle, NULL, NULL, NULL, &isb, buffer, (ULONG)isb.Information, // number of bytes read NULL, NULL ); if (!NT_SUCCESS(status)) { wprintf(L"Error writing to output file: %s\n", PhGetNtMessage(status)->Buffer); break; } bytesToCopy -= (ULONG)isb.Information; } PhFreePage(buffer); // Copy basic attributes over. if (NT_SUCCESS(NtQueryInformationFile( fileHandle, &isb, &basicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation ))) { NtSetInformationFile( outFileHandle, &isb, &basicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation ); } NtClose(fileHandle); NtClose(outFileHandle); } } else if (PhEqualString2(FiArgAction, L"dir", TRUE)) { HANDLE fileHandle; UNICODE_STRING pattern; PPH_STRING totalSize, totalAllocSize; if (FiCreateFile( &fileHandle, FILE_LIST_DIRECTORY | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { FipDirFileCount = 0; FipDirDirCount = 0; FipDirTotalSize = 0; FipDirTotalAllocSize = 0; if (FiArgPattern) PhStringRefToUnicodeString(&FiArgPattern->sr, &pattern); PhEnumDirectoryFile( fileHandle, FiArgPattern ? &pattern : NULL, FipEnumDirectoryFileForDir, NULL ); NtClose(fileHandle); totalSize = PhFormatUInt64(FipDirTotalSize, TRUE); totalAllocSize = PhFormatUInt64(FipDirTotalAllocSize, TRUE); wprintf( L"%12I64u file(s) %11s bytes\n" L"%12I64u dir(s) %11s bytes allocated\n", FipDirFileCount, totalSize->Buffer, FipDirDirCount, totalAllocSize->Buffer ); PhDereferenceObject(totalSize); PhDereferenceObject(totalAllocSize); } } else if (PhEqualString2(FiArgAction, L"streams", TRUE)) { HANDLE fileHandle; PVOID streams; PFILE_STREAM_INFORMATION stream; if (FiCreateFile( &fileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FiArgFileName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) { if (NT_SUCCESS(PhEnumFileStreams(fileHandle, &streams))) { stream = PH_FIRST_STREAM(streams); while (stream) { PPH_STRING size, allocationSize; size = PhFormatUInt64(stream->StreamSize.QuadPart, TRUE); allocationSize = PhFormatUInt64(stream->StreamAllocationSize.QuadPart, TRUE); wprintf( L"%11s %11s %.*s\n", size->Buffer, allocationSize->Buffer, stream->StreamNameLength / 2, stream->StreamName ); PhDereferenceObject(size); PhDereferenceObject(allocationSize); stream = PH_NEXT_STREAM(stream); } } NtClose(fileHandle); } } else { wprintf(L"Error: invalid action \"%s\".\n", FiArgAction->Buffer); FiPrintHelp(); return 1; } }
/* * SfcIsFileLegit * * Purpose: * * Verify file to be legit ZeroAccess signed binary. * * Verification algorithm (as for current version) * * 1. Open dll file, read it to the allocated buffer, read extended attribute VER, * containing retL packet data regarding file FileName, TimeStamp, FileSize, * Signature (unusued in this verification); * * 2. Import required RSA key (hardcoded in the bot); * * 3. Calc MD5 for FileName+TimeStamp+FileSize values; * * 4. Find resource [1] in dll file, which is embedded signature used to check; * * 5. Remember PE header CRC value, set it to zero in PE file buffer; * * 6. Copy embedded signature [1] to preallocated buffer, zero it in PE file buffer; * * 7. Update MD5 for PE file buffer (excluding PE CRC and signature); * * 8. Use result MD5 as hash value; * * 9. Verify embedded signature. * * If anything from the above fail - file is not legit by ZeroAccess opinion. * * If you copy ZeroAccess downloaded files without copying EA data, it cannot be verified. * */ NTSTATUS SfcIsFileLegit( _In_ LPWSTR lpFileName, _In_ PBYTE BotKey, _In_ DWORD BotKeySize ) { BOOL cond = FALSE; PVOID pBuffer; MD5_CTX context; ZA_FILEHEADER zaHeader; HCRYPTPROV lh_prov = 0; HCRYPTKEY lh_key = 0; HANDLE hFile = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING usFileName; SIZE_T memIO = 0; if ( (lpFileName == NULL) || (BotKey == NULL) || (BotKeySize == 0) ) { return status; } RtlSecureZeroMemory(&usFileName, sizeof(usFileName)); do { if (RtlDosPathNameToNtPathName_U(lpFileName, &usFileName, NULL, NULL) == FALSE) break; InitializeObjectAttributes(&ObjectAttributes, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); status = NtOpenFile(&hFile, FILE_GENERIC_READ, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); if (!NT_SUCCESS(status)) break; RtlFreeUnicodeString(&usFileName); RtlSecureZeroMemory(&zaHeader, sizeof(zaHeader)); if (!SfNtfsQueryFileHeaderFromEa(hFile, &zaHeader)) { status = STATUS_EA_LIST_INCONSISTENT; break; } status = STATUS_UNSUCCESSFUL; memIO = zaHeader.Size; pBuffer = NULL; if ( (NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(), &pBuffer, 0, &memIO, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) && (pBuffer != NULL) ) { if (NT_SUCCESS(NtReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, pBuffer, zaHeader.Size, NULL, NULL))) { if (CryptAcquireContext(&lh_prov, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { if (CryptImportKey(lh_prov, (const BYTE *)BotKey, BotKeySize, 0, 0, &lh_key)) { RtlSecureZeroMemory(&context, sizeof(context)); MD5Init(&context); MD5Update(&context, (UCHAR*)&zaHeader, (UINT)3 * sizeof(ULONG)); //note: ZA_FILEHEADER without signature if (SfcVerifyFile(lh_prov, lh_key, &context, pBuffer, zaHeader.Size)) status = STATUS_SUCCESS; CryptDestroyKey(lh_key); } CryptReleaseContext(lh_prov, 0); } } memIO = 0; NtFreeVirtualMemory(NtCurrentProcess(), &pBuffer, &memIO, MEM_RELEASE); } NtClose(hFile); hFile = NULL; } while (cond); if (hFile != NULL) NtClose(hFile); if (usFileName.Buffer != NULL) { RtlFreeUnicodeString(&usFileName); } return status; }
static VOID AddDiskToList( HANDLE FileHandle, ULONG DiskNumber) { DISK_GEOMETRY DiskGeometry; SCSI_ADDRESS ScsiAddress; PDISKENTRY DiskEntry; IO_STATUS_BLOCK Iosb; NTSTATUS Status; PPARTITION_SECTOR Mbr; PULONG Buffer; LARGE_INTEGER FileOffset; WCHAR Identifier[20]; ULONG Checksum; ULONG Signature; ULONG i; PLIST_ENTRY ListEntry; PBIOSDISKENTRY BiosDiskEntry; ULONG LayoutBufferSize; PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer; Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &DiskGeometry, sizeof(DISK_GEOMETRY)); if (!NT_SUCCESS(Status)) { return; } if (DiskGeometry.MediaType != FixedMedia && DiskGeometry.MediaType != RemovableMedia) { return; } Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, IOCTL_SCSI_GET_ADDRESS, NULL, 0, &ScsiAddress, sizeof(SCSI_ADDRESS)); if (!NT_SUCCESS(Status)) { return; } Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(RtlGetProcessHeap(), 0, DiskGeometry.BytesPerSector); if (Mbr == NULL) { return; } FileOffset.QuadPart = 0; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &Iosb, (PVOID)Mbr, DiskGeometry.BytesPerSector, &FileOffset, NULL); if (!NT_SUCCESS(Status)) { RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr); DPRINT1("NtReadFile failed, status=%x\n", Status); return; } Signature = Mbr->Signature; /* Calculate the MBR checksum */ Checksum = 0; Buffer = (PULONG)Mbr; for (i = 0; i < 128; i++) { Checksum += Buffer[i]; } Checksum = ~Checksum + 1; swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature); DPRINT("Identifier: %S\n", Identifier); DiskEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISKENTRY)); if (DiskEntry == NULL) { return; } // DiskEntry->Checksum = Checksum; // DiskEntry->Signature = Signature; DiskEntry->BiosFound = FALSE; /* Check if this disk has a valid MBR */ if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0) DiskEntry->NoMbr = TRUE; else DiskEntry->NoMbr = FALSE; /* Free Mbr sector buffer */ RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr); ListEntry = BiosDiskListHead.Flink; while (ListEntry != &BiosDiskListHead) { BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry); /* FIXME: * Compare the size from bios and the reported size from driver. * If we have more than one disk with a zero or with the same signatur * we must create new signatures and reboot. After the reboot, * it is possible to identify the disks. */ if (BiosDiskEntry->Signature == Signature && BiosDiskEntry->Checksum == Checksum && !BiosDiskEntry->Recognized) { if (!DiskEntry->BiosFound) { DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber; DiskEntry->BiosFound = TRUE; BiosDiskEntry->Recognized = TRUE; } else { } } ListEntry = ListEntry->Flink; } if (!DiskEntry->BiosFound) { #if 0 RtlFreeHeap(ProcessHeap, 0, DiskEntry); return; #else DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber); #endif } InitializeListHead(&DiskEntry->PrimaryPartListHead); InitializeListHead(&DiskEntry->LogicalPartListHead); DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart; DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder; DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack; DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector; DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders); DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder); DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack); DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector); DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart * (ULONGLONG)DiskGeometry.TracksPerCylinder * (ULONGLONG)DiskGeometry.SectorsPerTrack; DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack; DiskEntry->CylinderAlignment = DiskGeometry.SectorsPerTrack * DiskGeometry.TracksPerCylinder; DPRINT1("SectorCount: %I64u\n", DiskEntry->SectorCount); DPRINT1("SectorAlignment: %lu\n", DiskEntry->SectorAlignment); DPRINT1("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment); DiskEntry->DiskNumber = DiskNumber; DiskEntry->Port = ScsiAddress.PortNumber; DiskEntry->Bus = ScsiAddress.PathId; DiskEntry->Id = ScsiAddress.TargetId; GetDriverName(DiskEntry); InsertAscendingList(&DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber); /* Allocate a layout buffer with 4 partition entries first */ LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION)); DiskEntry->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, LayoutBufferSize); if (DiskEntry->LayoutBuffer == NULL) { DPRINT1("Failed to allocate the disk layout buffer!\n"); return; } for (;;) { DPRINT1("Buffer size: %lu\n", LayoutBufferSize); Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, 0, DiskEntry->LayoutBuffer, LayoutBufferSize); if (NT_SUCCESS(Status)) break; if (Status != STATUS_BUFFER_TOO_SMALL) { DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status); return; } LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION); NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, DiskEntry->LayoutBuffer, LayoutBufferSize); if (NewLayoutBuffer == NULL) { DPRINT1("Failed to reallocate the disk layout buffer!\n"); return; } DiskEntry->LayoutBuffer = NewLayoutBuffer; } DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount); #ifdef DUMP_PARTITION_TABLE DumpPartitionTable(DiskEntry); #endif if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 && DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 && DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != 0) { if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0) { DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack); } else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0) { DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector); } else { DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart); } } else { DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector); } if (DiskEntry->LayoutBuffer->PartitionCount == 0) { DiskEntry->NewDisk = TRUE; DiskEntry->LayoutBuffer->PartitionCount = 4; for (i = 0; i < 4; i++) DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE; } else { for (i = 0; i < 4; i++) { AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE); } for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4) { AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE); } } ScanForUnpartitionedDiskSpace(DiskEntry); }
DWORD WINAPI CommandPipe(LPVOID lpThreadParameter) { DWORD command; BYTE buff[0x400]={}; HANDLE hPipeExist; hPipeExist=IthOpenEvent(exist); IO_STATUS_BLOCK ios={0}; NTSTATUS status; if (hPipeExist!=INVALID_HANDLE_VALUE) while (running) { while (!live) { if (!running) goto _detach; NtDelayExecution(0,&sleep_time); } status=NtReadFile(hCommand,0,0,0,&ios,buff,0x200,0,0); if (status==STATUS_PIPE_BROKEN|| status==STATUS_PIPE_DISCONNECTED) { NtClearEvent(hPipeExist); continue; } if (status==STATUS_PENDING) { NtWaitForSingleObject(hCommand,0,0); switch (ios.Status) { case 0: break; case STATUS_PIPE_BROKEN: case STATUS_PIPE_DISCONNECTED: NtClearEvent(hPipeExist); continue; break; default: if (NtWaitForSingleObject(hDetach,0,&wait_time)==WAIT_OBJECT_0) goto _detach; } } if (ios.uInformation) if (live) { command=*(DWORD*)buff; switch(command) { case IHF_COMMAND_NEW_HOOK: //IthBreak(); buff[ios.uInformation] = 0; buff[ios.uInformation + 1] = 0; NewHook(*(HookParam*)(buff+4),(LPWSTR)(buff + 4 + sizeof(HookParam)),0); break; case IHF_COMMAND_REMOVE_HOOK: { DWORD rm_addr=*(DWORD*)(buff+4); HANDLE hRemoved=IthOpenEvent(L"ITH_REMOVE_HOOK"); TextHook* in=hookman; int i; for (i=0;i<current_hook;in++) { if (in->Address()) i++; if (in->Address()==rm_addr) break; } if (in->Address()) in->ClearHook(); IthSetEvent(hRemoved); NtClose(hRemoved); break; } case IHF_COMMAND_MODIFY_HOOK: { DWORD rm_addr=*(DWORD*)(buff+4); HANDLE hModify=IthOpenEvent(L"ITH_MODIFY_HOOK"); TextHook* in=hookman; int i; for (i=0;i<current_hook;in++) { if (in->Address()) i++; if (in->Address()==rm_addr) break; } if (in->Address()) in->ModifyHook(*(HookParam*)(buff+4)); IthSetEvent(hModify); NtClose(hModify); break; } break; case IHF_COMMAND_DETACH: running=false; live=false; goto _detach; default: break; } } } _detach: NtClose(hPipeExist); NtClose(hCommand); return 0; }
DWORD __stdcall PipeThread( VOID* Parameter ) { HANDLE pipeHandle; BYTE buffer[1024]; OBJECT_ATTRIBUTES objAttributes; UNICODE_STRING pipeName; IO_STATUS_BLOCK isb; LARGE_INTEGER timeOut; RtlDosPathNameToNtPathName_U(L"\\\\.\\pipe\\Push", &pipeName, NULL, NULL); objAttributes.Length = sizeof(OBJECT_ATTRIBUTES); objAttributes.RootDirectory = NULL; objAttributes.ObjectName = &pipeName; objAttributes.Attributes = OBJ_CASE_INSENSITIVE; objAttributes.SecurityDescriptor = NULL; objAttributes.SecurityQualityOfService = NULL; timeOut.QuadPart = 0xfffffffffff85ee0; NtCreateNamedPipeFile( &pipeHandle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &objAttributes, &isb, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, 0, 0, 0, 1, 1024 * 16, 1024 * 16, &timeOut ); while (pipeHandle != INVALID_HANDLE_VALUE) { if (ConnectNamedPipe(pipeHandle, NULL) != FALSE) // wait for someone to connect to the pipe { IO_STATUS_BLOCK isb; while (NtReadFile( pipeHandle, NULL, NULL, NULL, &isb, buffer, sizeof(buffer) - 1, NULL, NULL ) == STATUS_SUCCESS) { /* parse command buffer */ COMMAND_HEADER *cmdBuffer; cmdBuffer = &buffer; switch (cmdBuffer->CommandIndex) { case CMD_STARTHWMON: { OnRenderEvent(); }break; case CMD_NOTIFY: { UINT16 responseTime; OnProcessEvent(cmdBuffer->ProcessId); File_Write(pipeHandle, &responseTime, 2); }break; case CMD_SETGPUCLK: if (PushSharedMemory->HarwareInformation.DisplayDevice.EngineClockMax > 1 && PushSharedMemory->HarwareInformation.DisplayDevice.MemoryClockMax > 1 ) { GPU_CONFIG_CMD_BUFFER *gpuConfig; gpuConfig = &buffer; GPU_SetEngineClock(gpuConfig->EngineClock); GPU_SetMemoryClock(gpuConfig->MemoryClock); GPU_SetVoltage(gpuConfig->Voltage); } break; case CMD_MAXGPUCLK: Hardware_ForceMaxClocks(); break; case CMD_SETGPUFAN: Adl_SetFanDutyCycle(PushSharedMemory->HarwareInformation.DisplayDevice.FanDutyCycle); break; case CMD_GETDSKRSP: { UINT32 processId; UINT16 responseTime; processId = cmdBuffer->ProcessId; responseTime = GetDiskResponseTime(processId); File_Write(pipeHandle, &responseTime, 2); }break; case CMD_CONTROLLERCFG: { CONTROLLER_CONFIG_CMD_BUFFER *cmdBuffer; cmdBuffer = &buffer; SetButtonMapping(&cmdBuffer->Map); }break; case CMD_SAVEPRFL: { CONTROLLER_CONFIG_CMD_BUFFER *cmdBuffer; wchar_t fileName[260]; cmdBuffer = &buffer; CreatePath(L".\\" GAMES_CONFIG_PATH); GetConfigFileFromProcessId(cmdBuffer->CommandHeader.ProcessId, fileName); WriteConfig(L"ButtonTriangle", cmdBuffer->Map.Triangle, fileName); WriteConfig(L"ButtonCircle", cmdBuffer->Map.Circle, fileName); WriteConfig(L"ButtonCross", cmdBuffer->Map.Cross, fileName); WriteConfig(L"ButtonSquare", cmdBuffer->Map.Square, fileName); WriteConfig(L"DPadUp", cmdBuffer->Map.DpadUp, fileName); WriteConfig(L"DPadRight", cmdBuffer->Map.DpadRight, fileName); WriteConfig(L"DPadDown", cmdBuffer->Map.DpadDown, fileName); WriteConfig(L"DPadLeft", cmdBuffer->Map.DpadLeft, fileName); WriteConfig(L"ButtonL1", cmdBuffer->Map.L1, fileName); WriteConfig(L"ButtonR1", cmdBuffer->Map.R1, fileName); WriteConfig(L"ButtonL2", cmdBuffer->Map.L2, fileName); WriteConfig(L"ButtonR2", cmdBuffer->Map.R2, fileName); WriteConfig(L"ButtonL3", cmdBuffer->Map.L3, fileName); WriteConfig(L"ButtonR3", cmdBuffer->Map.R3, fileName); WriteConfig(L"ButtonSelect", cmdBuffer->Map.Select, fileName); WriteConfig(L"ButtonStart", cmdBuffer->Map.Start, fileName); WriteConfig(L"ButtonPS", cmdBuffer->Map.PS, fileName); WriteConfig(L"LeftStickXpos", cmdBuffer->Map.LStick_Xpos, fileName); WriteConfig(L"LeftStickXneg", cmdBuffer->Map.LStick_Xneg, fileName); WriteConfig(L"LeftStickYpos", cmdBuffer->Map.LStick_Ypos, fileName); WriteConfig(L"LeftStickYneg", cmdBuffer->Map.LStick_Yneg, fileName); WriteConfig(L"RightStickXpos", 0, fileName); WriteConfig(L"RightStickXneg", 0, fileName); WriteConfig(L"RightStickYpos", 0, fileName); WriteConfig(L"RightStickYneg", 0, fileName); }break; case CMD_BRIGHTNESS: { CMD_BUFFER_BRIGHTNESS* cmdBuffer; cmdBuffer = &buffer; SetBrightness(cmdBuffer->Brightness); }break; } } } DisconnectNamedPipe(pipeHandle); } return 0; }
/* * SfuLoadPeerList * * Purpose: * * Load peer list from filename given in win32 format. * */ NTSTATUS SfuLoadPeerList( _In_ OBJECT_ATTRIBUTES *ObjectAttributes, _In_ ZA_PEERINFO **PeerList, _In_ PULONG NumberOfPeers ) { BOOL cond = FALSE; HANDLE hFile = NULL; PVOID pData = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; IO_STATUS_BLOCK iost; FILE_STANDARD_INFORMATION fsi; if ((NumberOfPeers == NULL) || (PeerList == NULL)) return status; do { status = NtOpenFile(&hFile, FILE_READ_ACCESS | SYNCHRONIZE, ObjectAttributes, &iost, FILE_SHARE_READ, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(status)) break; RtlSecureZeroMemory(&fsi, sizeof(fsi)); status = NtQueryInformationFile(hFile, &iost, (PVOID)&fsi, sizeof(fsi), FileStandardInformation); if (!NT_SUCCESS(status)) break; pData = RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, (SIZE_T)fsi.EndOfFile.LowPart); if (pData == NULL) { status = STATUS_MEMORY_NOT_ALLOCATED; break; } if ((fsi.EndOfFile.LowPart % sizeof(ZA_PEERINFO)) != 0) {// incomplete/damaged file status = STATUS_BAD_DATA; break; } status = NtReadFile(hFile, NULL, NULL, NULL, &iost, pData, fsi.EndOfFile.LowPart, NULL, NULL); if (NT_SUCCESS(status)) { *NumberOfPeers = (ULONG)(iost.Information / sizeof(ZA_PEERINFO)); *PeerList = pData; } else { RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, pData); *NumberOfPeers = 0; *PeerList = NULL; } } while (cond); if (hFile) NtClose(hFile); return status; }