NTSTATUS Disk_GetPartitionLinkName(PWCHAR DriveLetter, WCHAR* pwchName, USHORT NameLen) { PDEVICE_OBJECT pDevice = NULL; PFILE_OBJECT pFileObject; NTSTATUS ntStatusRet = STATUS_UNSUCCESSFUL; UNICODE_STRING ObjectName; RtlInitUnicodeString(&ObjectName, DriveLetter); if (ObjectName.Length == sizeof(WCHAR)) { NTSTATUS ntStatus; HANDLE hDir; UNICODE_STRING us; OBJECT_ATTRIBUTES ObjAttr; HANDLE hLink; UNICODE_STRING targetNameUnicodeString; PFILE_OBJECT fileObject; IO_STATUS_BLOCK ioStatus; WCHAR cDrive[3] = L"A:"; RtlInitUnicodeString(&us, (PWCHAR)L"\\??"); InitializeObjectAttributes(&ObjAttr, &us, OBJ_CASE_INSENSITIVE, NULL, NULL); ntStatus = ZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY,&ObjAttr); if(!NT_SUCCESS(ntStatus)) { DbPrint(DC_LLDISKIO, DL_ERROR, ("ZwOpenDirectoryObject %S failed, status %x\n",us.Buffer, ntStatus)); return ntStatusRet; } cDrive[0] = DriveLetter[0]; RtlInitUnicodeString(&us,cDrive); InitializeObjectAttributes(&ObjAttr, &us, OBJ_CASE_INSENSITIVE, hDir, NULL); ntStatus = ZwOpenSymbolicLinkObject(&hLink, SYMBOLIC_LINK_QUERY, &ObjAttr); if(NT_SUCCESS(ntStatus)) { RtlZeroMemory(pwchName, NameLen); targetNameUnicodeString.Buffer = pwchName; targetNameUnicodeString.MaximumLength = NameLen; ntStatus = ZwQuerySymbolicLinkObject(hLink, &targetNameUnicodeString, NULL); if(NT_SUCCESS(ntStatus)) { if(!wcsncmp(pwchName,L"\\Device",7)) ntStatusRet = STATUS_SUCCESS; } ZwClose(hLink); } ZwClose(hDir); } return ntStatusRet; }
NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject) { PAGED_CODE(); UNICODE_STRING PartialName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE Handle; NTSTATUS Result; PartialName.Length = 0; PartialName.MaximumLength = ObjectName->Length; PartialName.Buffer = ObjectName->Buffer; Result = STATUS_NO_SUCH_DEVICE; while (PartialName.MaximumLength > PartialName.Length) { while (PartialName.MaximumLength > PartialName.Length && L'\\' == PartialName.Buffer[PartialName.Length / sizeof(WCHAR)]) PartialName.Length += sizeof(WCHAR); while (PartialName.MaximumLength > PartialName.Length && L'\\' != PartialName.Buffer[PartialName.Length / sizeof(WCHAR)]) PartialName.Length += sizeof(WCHAR); Result = IoGetDeviceObjectPointer(&PartialName, DesiredAccess, PFileObject, PDeviceObject); if (NT_SUCCESS(Result)) { *PFileNameIndex = PartialName.Length; break; } InitializeObjectAttributes(&ObjectAttributes, &PartialName, OBJ_KERNEL_HANDLE, 0, 0); Result = ZwOpenDirectoryObject(&Handle, 0, &ObjectAttributes); if (!NT_SUCCESS(Result)) { Result = ZwOpenSymbolicLinkObject(&Handle, 0, &ObjectAttributes); if (!NT_SUCCESS(Result)) { Result = STATUS_NO_SUCH_DEVICE; break; } } ZwClose(Handle); } return Result; }
// ----------------------------------------------------------------------------------------- PDEVICE_OBJECT Disk_GetDeviceObjectByLetter(WCHAR DriveLetter) { PDEVICE_OBJECT pDevice = NULL; NTSTATUS ntStatus; HANDLE hDir; UNICODE_STRING us; OBJECT_ATTRIBUTES ObjAttr; HANDLE hLink; WCHAR targetNameBuffer[260]; UNICODE_STRING targetNameUnicodeString; PFILE_OBJECT fileObject; IO_STATUS_BLOCK ioStatus; WCHAR cDrive[3] = L"A:"; RtlInitUnicodeString(&us, (PWCHAR)L"\\??"); InitializeObjectAttributes(&ObjAttr, &us, OBJ_CASE_INSENSITIVE, NULL, NULL); ntStatus = ZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY,&ObjAttr); if(!NT_SUCCESS(ntStatus)) { DbPrint(DC_LLDISKIO, DL_ERROR, ("ZwOpenDirectoryObject %S failed, status %x\n",us.Buffer, ntStatus)); return NULL; } cDrive[0] = DriveLetter; RtlInitUnicodeString(&us,cDrive); InitializeObjectAttributes(&ObjAttr, &us, OBJ_CASE_INSENSITIVE, hDir, NULL); ntStatus = ZwOpenSymbolicLinkObject(&hLink, SYMBOLIC_LINK_QUERY, &ObjAttr); if(NT_SUCCESS(ntStatus)) { RtlZeroMemory(targetNameBuffer, sizeof(targetNameBuffer)); targetNameUnicodeString.Buffer = targetNameBuffer; targetNameUnicodeString.MaximumLength = sizeof(targetNameBuffer); ntStatus = ZwQuerySymbolicLinkObject(hLink, &targetNameUnicodeString, NULL); if(NT_SUCCESS(ntStatus)) { if(!wcsncmp(targetNameBuffer,L"\\Device",7)) { HANDLE hFile; ntStatus = ZwCreateFile(&hFile, SYNCHRONIZE | FILE_ANY_ACCESS, &ObjAttr, &ioStatus, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if(NT_SUCCESS(ntStatus)) { //!FILE_DEVICE_MASS_STORAGE or FILE_DEVICE_TAPE ntStatus = ObReferenceObjectByHandle(hFile, FILE_READ_DATA, NULL, KernelMode, (PVOID*) &fileObject, NULL); if(NT_SUCCESS(ntStatus)) { pDevice = fileObject->DeviceObject; if (pDevice->Vpb != NULL) { if (pDevice->Vpb->RealDevice != NULL) pDevice = pDevice->Vpb->RealDevice; } if(pDevice->DeviceType == FILE_DEVICE_DISK || pDevice->DeviceType == FILE_DEVICE_CD_ROM || pDevice->DeviceType == FILE_DEVICE_DVD) { if(!NT_SUCCESS(ObReferenceObjectByPointer(pDevice, STANDARD_RIGHTS_REQUIRED, *IoDeviceObjectType, KernelMode))) //dereference will be in caller proc pDevice = NULL; } else pDevice = NULL; ObDereferenceObject(fileObject); } ZwClose(hFile); } } } ZwClose(hLink); } ZwClose(hDir); return pDevice; }
NTSTATUS FindHardDiskForPartition(PUNICODE_STRING pNameUnicodeString, PWCHAR pOutRequest, ULONG OutRequestSize, ULONG *pRetSize) { NTSTATUS ntRetStatus = STATUS_NOT_FOUND; NTSTATUS ntStatus; BYTE cou; OBJECT_ATTRIBUTES ObjAttr; HANDLE hDirectoryObject; BOOLEAN First; POBJECT_NAMETYPE_INFO p; HANDLE DrvHandle; PDRIVER_OBJECT pDrv; UNICODE_STRING Name; PWCHAR DrvName; PWCHAR DriverStr=L"Partition"; WCHAR Dir[128]; ULONG RegionSize; PMY_QUERY_DIRECTORY_STRUCT qds; qds = NULL; RegionSize = sizeof(MY_QUERY_DIRECTORY_STRUCT); if(!NT_SUCCESS(ntStatus = ZwAllocateVirtualMemory((HANDLE)-1, (PVOID*) &qds, 0, &RegionSize, // ^ - Whistler beta 2 doesn't work with 8 MEM_COMMIT,PAGE_READWRITE))) { DbPrint(DC_LLDISKIO, DL_ERROR,("ZwAllocateVirtualMemory fail. Status=%x\n", ntStatus)); } else { PWCHAR pdrvid; for(cou = 0; cou <= 9 && ntRetStatus != STATUS_SUCCESS; cou++) { wcscpy(Dir, L"\\Device\\Harddisk0"); pdrvid = &Dir[wcslen(Dir) - 1]; *(BYTE*)pdrvid += cou; RtlInitUnicodeString(&Name, Dir); InitializeObjectAttributes(&ObjAttr, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL); ntStatus=ZwOpenDirectoryObject(&hDirectoryObject, DIRECTORY_QUERY, &ObjAttr); if(NT_SUCCESS(ntStatus)) { First=TRUE; DrvName=Dir+wcslen(Dir); *DrvName++='\\'; while(NtQueryDirectoryObject(hDirectoryObject, &qds->Buffer, QUERY_DIRECTORY_BUFF_SIZE, TRUE, First, &qds->Index, &qds->Retlen) >= 0 && ntRetStatus != STATUS_SUCCESS) { p=(POBJECT_NAMETYPE_INFO)&qds->Buffer; First=FALSE; *DrvName=0; if(wcsncmp(p->ObjectName.Buffer, DriverStr, 9)) continue; else { HANDLE hLink; InitializeObjectAttributes(&ObjAttr, &p->ObjectName, OBJ_CASE_INSENSITIVE, hDirectoryObject, NULL); ntStatus = ZwOpenSymbolicLinkObject(&hLink, SYMBOLIC_LINK_QUERY, &ObjAttr); if(NT_SUCCESS(ntStatus)) { WCHAR targetNameBuffer[260]; UNICODE_STRING targetNameUnicodeString; RtlZeroMemory(targetNameBuffer, sizeof(targetNameBuffer)); targetNameUnicodeString.Buffer = targetNameBuffer; targetNameUnicodeString.MaximumLength = sizeof(targetNameBuffer); ntStatus = ZwQuerySymbolicLinkObject(hLink, &targetNameUnicodeString, NULL); if(NT_SUCCESS(ntStatus) && (RtlCompareUnicodeString(&targetNameUnicodeString, pNameUnicodeString, FALSE) == 0)) { int number = GetHarddiskId(Dir); if (number != -1) { int cou2; int drvstrlen; char drstr[32]; sprintf(drstr, "%d", number); drvstrlen = strlen(drstr); wcscpy(pOutRequest, Dir); wcscat(pOutRequest, L"DR"); pdrvid = &pOutRequest[wcslen(pOutRequest) - 1] + 1; for (cou2 = 0; cou2 < drvstrlen; cou2++) { *pdrvid = (WCHAR) (drstr[cou2]); pdrvid++; } *pdrvid = 0; DbPrint(DC_LLDISKIO, DL_INFO, ("FindHardDiskForPartition found %S\n", pOutRequest)); *pRetSize = (wcslen(pOutRequest) + 1 ) * 2; ntRetStatus = STATUS_SUCCESS; } } ZwClose(hLink); } } } ZwClose(hDirectoryObject); } } } RegionSize = 0; _pfZwFreeVirtualMemory((HANDLE)-1,(PVOID*) &qds,&RegionSize,MEM_RELEASE); return ntRetStatus; }
int GetHarddiskId(PWCHAR pwchDir) { NTSTATUS ntStatus; int nRet = -1; OBJECT_ATTRIBUTES ObjAttr; HANDLE hDirectoryObject; UNICODE_STRING Name; WCHAR DriverStr[32]; PWCHAR pdrvid; int len ; PMY_QUERY_DIRECTORY_STRUCT qds; POBJECT_NAMETYPE_INFO p; ULONG RegionSize; int cou; qds = NULL; RegionSize = sizeof(MY_QUERY_DIRECTORY_STRUCT); if(!NT_SUCCESS(ntStatus = ZwAllocateVirtualMemory((HANDLE)-1, (PVOID*) &qds, 0, &RegionSize, MEM_COMMIT,PAGE_READWRITE))) { return nRet; } wcscpy(DriverStr, L"DR0"); len = wcslen(DriverStr); pdrvid = &DriverStr[len - 1]; RtlInitUnicodeString(&Name, pwchDir); Name.Length -= sizeof(WCHAR); InitializeObjectAttributes(&ObjAttr, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL); ntStatus = ZwOpenDirectoryObject(&hDirectoryObject, DIRECTORY_QUERY, &ObjAttr); if(NT_SUCCESS(ntStatus)) { BOOLEAN First = TRUE; while(NtQueryDirectoryObject(hDirectoryObject, &qds->Buffer, QUERY_DIRECTORY_BUFF_SIZE, TRUE, First, &qds->Index, &qds->Retlen) >= 0 && nRet == -1) { PWCHAR obj_name; int tmp_len; p = (POBJECT_NAMETYPE_INFO)&qds->Buffer; First = FALSE; obj_name = p->ObjectName.Buffer; tmp_len = p->ObjectName.Length / sizeof(WCHAR); if (tmp_len >= 3) { // TAK POLUCHILOS! :) if (obj_name[0] == L'D' && obj_name[1] == L'R') { BOOLEAN bisdigit = TRUE; int cou2; int ntmp = 0; for (cou2 = 2; cou2 < tmp_len; cou2++) { if (obj_name[cou2] < L'0' || obj_name[cou2] > L'9') { bisdigit = FALSE; break; } ntmp = ntmp * 10 + (obj_name[cou2] - L'0'); } if (bisdigit) nRet = ntmp; } } } ZwClose(hDirectoryObject); } _pfZwFreeVirtualMemory((HANDLE)-1,(PVOID*) &qds, &RegionSize,MEM_RELEASE); return nRet; }
static NTSTATUS FASTCALL BuildWindowStationNameList( ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize) { OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE DirectoryHandle; char InitialBuffer[256], *Buffer; ULONG Context, ReturnLength, BufferSize; DWORD EntryCount; POBJECT_DIRECTORY_INFORMATION DirEntry; WCHAR NullWchar; /* * Try to open the directory. */ InitializeObjectAttributes(&ObjectAttributes, &gustrWindowStationsDir, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenDirectoryObject(&DirectoryHandle, DIRECTORY_QUERY, &ObjectAttributes); if (!NT_SUCCESS(Status)) { return Status; } /* First try to query the directory using a fixed-size buffer */ Context = 0; Buffer = NULL; Status = ZwQueryDirectoryObject(DirectoryHandle, InitialBuffer, sizeof(InitialBuffer), FALSE, TRUE, &Context, &ReturnLength); if (NT_SUCCESS(Status)) { if (STATUS_NO_MORE_ENTRIES == ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, FALSE, &Context, NULL)) { /* Our fixed-size buffer is large enough */ Buffer = InitialBuffer; } } if (NULL == Buffer) { /* Need a larger buffer, check how large exactly */ Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context, &ReturnLength); if (!NT_SUCCESS(Status)) { ERR("ZwQueryDirectoryObject failed\n"); ZwClose(DirectoryHandle); return Status; } BufferSize = ReturnLength; Buffer = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_WINSTA); if (NULL == Buffer) { ZwClose(DirectoryHandle); return STATUS_NO_MEMORY; } /* We should have a sufficiently large buffer now */ Context = 0; Status = ZwQueryDirectoryObject(DirectoryHandle, Buffer, BufferSize, FALSE, TRUE, &Context, &ReturnLength); if (! NT_SUCCESS(Status) || STATUS_NO_MORE_ENTRIES != ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, FALSE, &Context, NULL)) { /* Something went wrong, maybe someone added a directory entry? Just give up. */ ExFreePoolWithTag(Buffer, TAG_WINSTA); ZwClose(DirectoryHandle); return NT_SUCCESS(Status) ? STATUS_INTERNAL_ERROR : Status; } } ZwClose(DirectoryHandle); /* * Count the required size of buffer. */ ReturnLength = sizeof(DWORD); EntryCount = 0; for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer; 0 != DirEntry->Name.Length; DirEntry++) { ReturnLength += DirEntry->Name.Length + sizeof(WCHAR); EntryCount++; } TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount); if (NULL != pRequiredSize) { Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG)); if (! NT_SUCCESS(Status)) { if (Buffer != InitialBuffer) { ExFreePoolWithTag(Buffer, TAG_WINSTA); } return STATUS_BUFFER_TOO_SMALL; } } /* * Check if the supplied buffer is large enough. */ if (dwSize < ReturnLength) { if (Buffer != InitialBuffer) { ExFreePoolWithTag(Buffer, TAG_WINSTA); } return STATUS_BUFFER_TOO_SMALL; } /* * Generate the resulting buffer contents. */ Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD)); if (! NT_SUCCESS(Status)) { if (Buffer != InitialBuffer) { ExFreePoolWithTag(Buffer, TAG_WINSTA); } return Status; } lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD)); NullWchar = L'\0'; for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer; 0 != DirEntry->Name.Length; DirEntry++) { Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length); if (! NT_SUCCESS(Status)) { if (Buffer != InitialBuffer) { ExFreePoolWithTag(Buffer, TAG_WINSTA); } return Status; } lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length); Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR)); if (! NT_SUCCESS(Status)) { if (Buffer != InitialBuffer) { ExFreePoolWithTag(Buffer, TAG_WINSTA); } return Status; } lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR)); } /* * Clean up */ if (Buffer != InitialBuffer) { ExFreePoolWithTag(Buffer, TAG_WINSTA); } return STATUS_SUCCESS; }
NTSTATUS Mouse_Hook(IN PDRIVER_OBJECT driverObject) { ULONG i; int found = 1; NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION stack; UNICODE_STRING uniMouseDeviceName; PFILE_OBJECT mouseFileObject; PDEVICE_OBJECT MouseDeviceObject; ULONG counter; HANDLE hDir; OBJECT_ATTRIBUTES oa; UNICODE_STRING uniOa; PVOID pBuffer; PVOID pContext; ULONG RetLen; PDIRECTORY_BASIC_INFORMATION pDirBasicInfo; UNICODE_STRING uniMouseDrv; char* mouseclsNum; char arMouseCls[0x10]; WCHAR tmpNameBuffer[512]; DbgPrint("Running Mouse_Create."); RtlInitUnicodeString(&uniOa, L"\\Device"); InitializeObjectAttributes( &oa,&uniOa, OBJ_CASE_INSENSITIVE,NULL,NULL); status = ZwOpenDirectoryObject( &hDir,DIRECTORY_ALL_ACCESS,&oa); if(!NT_SUCCESS(status)) return status; pBuffer = ExAllocatePool(PagedPool, ALLOC_SIZE); pContext = ExAllocatePool(PagedPool, ALLOC_SIZE); // pBuffer = ExAllocatePoolWithTag(PagedPool, ALLOC_SIZE, Tag); // pContext = ExAllocatePoolWithTag(PagedPool, ALLOC_SIZE, Tag); memset(pBuffer, 0, ALLOC_SIZE); memset(pContext, 0, ALLOC_SIZE); memset(arMouseCls, 0, 0x10); counter = 0; g_Mouseclsnum = 0; while(TRUE) { status = ZwQueryDirectoryObject(hDir,pBuffer,ALLOC_SIZE,TRUE,FALSE,pContext,&RetLen); if(!NT_SUCCESS(status)) break; pDirBasicInfo = (PDIRECTORY_BASIC_INFORMATION)pBuffer; pDirBasicInfo->ObjectName.Length -= 2; RtlInitUnicodeString(&uniMouseDrv, L"PointerClass"); if(RtlCompareUnicodeString( &pDirBasicInfo->ObjectName, &uniMouseDrv,FALSE) == 0){ mouId = (ULONG)(*(char *)(pDirBasicInfo->ObjectName.Buffer+pDirBasicInfo->ObjectName.Length)); mouId -= 0x30; pDirBasicInfo->ObjectName.Length += 2; RtlInitUnicodeString(&uniMouseDeviceName, pDirBasicInfo->ObjectName.Buffer); found = 1; break; } pDirBasicInfo->ObjectName.Length += 2; } ExFreePool(pBuffer); ExFreePool(pContext); ZwClose(hDir); if( found == 0 ) return status; DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"Mouse_Hook ----> mouId[%d].\n", mouId); swprintf(tmpNameBuffer, L"\\Device\\%s", uniMouseDeviceName.Buffer); RtlInitUnicodeString(&uniMouseDeviceName, tmpNameBuffer); status = My_IoGetDeviceObjectPointer(&uniMouseDeviceName, FILE_ALL_ACCESS, &mouseFileObject,&MouseDeviceObject); if(NT_SUCCESS(status)) { g_MouseDeviceObject = MouseDeviceObject; ObDereferenceObject(mouseFileObject); g_OldReadFunction = g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_READ]; g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_READ] = Mouse_HookProc; g_OldInternalDeviceFunction = g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]; g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = Mouse_IO_InternalIoctl; DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"Mouse_Create ----> Mouse_HookProc success.\n"); } return status; }
void STDCALL look_for_vols(PDRIVER_OBJECT DriverObject, LIST_ENTRY* volumes) { PFILE_OBJECT FileObject; PDEVICE_OBJECT mountmgr; OBJECT_ATTRIBUTES attr; UNICODE_STRING mmdevpath, us; HANDLE h; OBJECT_DIRECTORY_INFORMATION* odi; ULONG odisize; ULONG context; BOOL restart; NTSTATUS Status; LIST_ENTRY* le; static const WCHAR directory[] = L"Directory"; static const WCHAR harddisk[] = L"Harddisk"; RtlInitUnicodeString(&mmdevpath, MOUNTMGR_DEVICE_NAME); Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &FileObject, &mountmgr); if (!NT_SUCCESS(Status)) { ERR("IoGetDeviceObjectPointer returned %08x\n", Status); return; } RtlInitUnicodeString(&us, devpath); attr.Length = sizeof(attr); attr.RootDirectory = 0; attr.Attributes = OBJ_CASE_INSENSITIVE; attr.ObjectName = &us; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; Status = ZwOpenDirectoryObject(&h, DIRECTORY_TRAVERSE, &attr); if (!NT_SUCCESS(Status)) { ERR("ZwOpenDirectoryObject returned %08x\n", Status); return; } odisize = sizeof(OBJECT_DIRECTORY_INFORMATION) * 16; odi = ExAllocatePoolWithTag(PagedPool, odisize, ALLOC_TAG); if (!odi) { ERR("out of memory\n"); ZwClose(h); return; } restart = TRUE; do { Status = ZwQueryDirectoryObject(h, odi, odisize, FALSE, restart, &context, NULL/*&retlen*/); restart = FALSE; if (!NT_SUCCESS(Status)) { if (Status != STATUS_NO_MORE_ENTRIES) ERR("ZwQueryDirectoryObject returned %08x\n", Status); } else { OBJECT_DIRECTORY_INFORMATION* odi2 = odi; while (odi2->Name.Buffer) { if (odi2->TypeName.Length == wcslen(directory) * sizeof(WCHAR) && RtlCompareMemory(odi2->TypeName.Buffer, directory, odi2->TypeName.Length) == odi2->TypeName.Length && odi2->Name.Length > wcslen(harddisk) * sizeof(WCHAR) && RtlCompareMemory(odi2->Name.Buffer, harddisk, wcslen(harddisk) * sizeof(WCHAR)) == wcslen(harddisk) * sizeof(WCHAR)) { look_in_harddisk_dir(DriverObject, mountmgr, &odi2->Name, volumes); } odi2 = &odi2[1]; } } } while (NT_SUCCESS(Status)); ExFreePool(odi); ZwClose(h); le = volumes->Flink; while (le != volumes) { volume* v = CONTAINING_RECORD(le, volume, list_entry); if (!v->processed) { LIST_ENTRY* le2 = le; volume* mountvol = v; while (le2 != volumes) { volume* v2 = CONTAINING_RECORD(le2, volume, list_entry); if (RtlCompareMemory(&v2->fsuuid, &v->fsuuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) { v2->processed = TRUE; if (v2->devnum < mountvol->devnum) { remove_drive_letter(mountmgr, mountvol); mountvol = v2; } else if (v2->devnum > mountvol->devnum) remove_drive_letter(mountmgr, v2); } le2 = le2->Flink; } add_volume(mountmgr, &mountvol->devpath); } le = le->Flink; } ObDereferenceObject(FileObject); }
static NTSTATUS look_in_harddisk_dir(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT mountmgr, PUNICODE_STRING name, LIST_ENTRY* volumes) { UNICODE_STRING path; OBJECT_ATTRIBUTES attr; NTSTATUS Status; HANDLE h; OBJECT_DIRECTORY_INFORMATION* odi; ULONG odisize, context; BOOL restart, has_part0 = FALSE, has_parts = FALSE; static const WCHAR partition[] = L"Partition"; static WCHAR partition0[] = L"Partition0"; path.Buffer = ExAllocatePoolWithTag(PagedPool, ((wcslen(devpath) + 1) * sizeof(WCHAR)) + name->Length, ALLOC_TAG); if (!path.Buffer) { ERR("out of memory\n"); return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyMemory(path.Buffer, devpath, wcslen(devpath) * sizeof(WCHAR)); path.Buffer[wcslen(devpath)] = '\\'; RtlCopyMemory(&path.Buffer[wcslen(devpath) + 1], name->Buffer, name->Length); path.Length = path.MaximumLength = ((wcslen(devpath) + 1) * sizeof(WCHAR)) + name->Length; attr.Length = sizeof(attr); attr.RootDirectory = 0; attr.Attributes = OBJ_CASE_INSENSITIVE; attr.ObjectName = &path; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; Status = ZwOpenDirectoryObject(&h, DIRECTORY_TRAVERSE, &attr); if (!NT_SUCCESS(Status)) { ERR("ZwOpenDirectoryObject returned %08x\n", Status); goto end; } odisize = sizeof(OBJECT_DIRECTORY_INFORMATION) * 16; odi = ExAllocatePoolWithTag(PagedPool, odisize, ALLOC_TAG); if (!odi) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; ZwClose(h); goto end; } restart = TRUE; do { Status = ZwQueryDirectoryObject(h, odi, odisize, FALSE, restart, &context, NULL/*&retlen*/); restart = FALSE; if (!NT_SUCCESS(Status)) { if (Status != STATUS_NO_MORE_ENTRIES) ERR("ZwQueryDirectoryObject returned %08x\n", Status); } else { OBJECT_DIRECTORY_INFORMATION* odi2 = odi; while (odi2->Name.Buffer) { TRACE("%.*S, %.*S\n", odi2->TypeName.Length / sizeof(WCHAR), odi2->TypeName.Buffer, odi2->Name.Length / sizeof(WCHAR), odi2->Name.Buffer); if (odi2->Name.Length > wcslen(partition) * sizeof(WCHAR) && RtlCompareMemory(odi2->Name.Buffer, partition, wcslen(partition) * sizeof(WCHAR)) == wcslen(partition) * sizeof(WCHAR)) { if (odi2->Name.Length == (wcslen(partition) + 1) * sizeof(WCHAR) && odi2->Name.Buffer[(odi2->Name.Length / sizeof(WCHAR)) - 1] == '0') { // Partition0 refers to the whole disk has_part0 = TRUE; } else { has_parts = TRUE; test_vol(DriverObject, mountmgr, &path, &odi2->Name, FALSE, volumes); } } odi2 = &odi2[1]; } } } while (NT_SUCCESS(Status)); // If disk had no partitions, test the whole disk if (!has_parts && has_part0) { UNICODE_STRING part0us; part0us.Buffer = partition0; part0us.Length = part0us.MaximumLength = wcslen(partition0) * sizeof(WCHAR); test_vol(DriverObject, mountmgr, &path, &part0us, TRUE, volumes); } ZwClose(h); ExFreePool(odi); Status = STATUS_SUCCESS; end: ExFreePool(path.Buffer); return Status; }
static VOID CheckDirectorySecurity__( _In_ PCWSTR DirectoryName, _In_ PSID ExpectedOwner, _In_ PSID ExpectedGroup, _In_ ULONG AceCount, _In_ PCSTR FileAndLine, ...) { NTSTATUS Status; UNICODE_STRING DirectoryNameString; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE DirectoryHandle; PSECURITY_DESCRIPTOR SecurityDescriptor; ULONG SecurityDescriptorSize; PSID Owner; PSID Group; PACL Dacl; PACL Sacl; BOOLEAN Present; BOOLEAN Defaulted; va_list Arguments; RtlInitUnicodeString(&DirectoryNameString, DirectoryName); InitializeObjectAttributes(&ObjectAttributes, &DirectoryNameString, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenDirectoryObject(&DirectoryHandle, READ_CONTROL | ACCESS_SYSTEM_SECURITY, &ObjectAttributes); ok_eq_hex(Status, STATUS_SUCCESS); if (skip(NT_SUCCESS(Status), "No directory (%ls)\n", DirectoryName)) { return; } Status = ZwQuerySecurityObject(DirectoryHandle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, NULL, 0, &SecurityDescriptorSize); ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL); if (skip(Status == STATUS_BUFFER_TOO_SMALL, "No security size (%ls)\n", DirectoryName)) { ObCloseHandle(DirectoryHandle, KernelMode); return; } SecurityDescriptor = ExAllocatePoolWithTag(PagedPool, SecurityDescriptorSize, 'dSmK'); ok(SecurityDescriptor != NULL, "Failed to allocate %lu bytes\n", SecurityDescriptorSize); if (skip(SecurityDescriptor != NULL, "No memory for descriptor (%ls)\n", DirectoryName)) { ObCloseHandle(DirectoryHandle, KernelMode); return; } Status = ZwQuerySecurityObject(DirectoryHandle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, SecurityDescriptor, SecurityDescriptorSize, &SecurityDescriptorSize); ok_eq_hex(Status, STATUS_SUCCESS); if (NT_SUCCESS(Status)) { Owner = NULL; Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, &Owner, &Defaulted); if (ExpectedOwner) CheckSid__(Owner, NO_SIZE, ExpectedOwner, FileAndLine); ok(Defaulted == FALSE, "Owner defaulted for %ls\n", DirectoryName); Group = NULL; Status = RtlGetGroupSecurityDescriptor(SecurityDescriptor, &Group, &Defaulted); if (ExpectedGroup) CheckSid__(Group, NO_SIZE, ExpectedGroup, FileAndLine); ok(Defaulted == FALSE, "Group defaulted for %ls\n", DirectoryName); Dacl = NULL; Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, &Present, &Dacl, &Defaulted); ok_eq_hex(Status, STATUS_SUCCESS); ok(Present == TRUE, "DACL not present for %ls\n", DirectoryName); ok(Defaulted == FALSE, "DACL defaulted for %ls\n", DirectoryName); va_start(Arguments, FileAndLine); VCheckAcl__(Dacl, AceCount, FileAndLine, Arguments); va_end(Arguments); Sacl = NULL; Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor, &Present, &Sacl, &Defaulted); ok_eq_hex(Status, STATUS_SUCCESS); ok(Present == FALSE, "SACL present for %ls\n", DirectoryName); ok(Defaulted == FALSE, "SACL defaulted for %ls\n", DirectoryName); ok(Sacl == NULL, "Sacl is %p for %ls\n", Sacl, DirectoryName); } ExFreePoolWithTag(SecurityDescriptor, 'dSmK'); ObCloseHandle(DirectoryHandle, KernelMode); }