void TestFsRtlAddToTunnelCache(ULONGLONG DirectoryKey, PUNICODE_STRING s_name, PUNICODE_STRING l_name, BOOLEAN KeyByShortName) { SIZE_T eq; LONG b; PUNICODE_STRING bs_name; PUNICODE_STRING bl_name; PVOID Bufb; PVOID Buf; Buf = ExAllocatePool(PagedPool, BufSize); ok(Buf != NULL, "Buff in TestFsRtlAddToTunnelCache is NULL after allocated memory\n"); Bufb = ExAllocatePool(PagedPool, BufSize); ok(Bufb != NULL, "Buff in TestFsRtlAddToTunnelCache is NULL after allocated memory\n"); // Allocate memory for the bufs_name bs_name = CopyUS(s_name); // Allocate memory for the l_name and bl_name bl_name = CopyUS(l_name); memset((void*)Buf, 0, BufSize); memset((void*)Bufb, 0, BufSize); FsRtlAddToTunnelCache(T, DirectoryKey, s_name, l_name, KeyByShortName, BufSize, Buf); eq = RtlCompareMemory((const VOID*)Buf, (const VOID*)Bufb, BufSize); ok( eq != sizeof(TUNNEL),"FsRtlAddToTunnelCache function did not change anything in the memory at the address Buf.\n"); b = RtlCompareUnicodeString(l_name, bl_name, TRUE); ok (b == 0, "long name after call FsRtlAddToTunnelCache != long name befo call FsRtlAddToTunnelCache\n\n"); b = RtlCompareUnicodeString(s_name, bs_name, TRUE); ok (b == 0, "short name after call FsRtlAddToTunnelCache != short name befo call FsRtlAddToTunnelCache\n\n"); }
UCHAR AndroidUsbDeviceObject::GetPipeIndexFromFileName( PUNICODE_STRING file_path) { ASSERT_IRQL_PASSIVE(); ASSERT((NULL != file_path) && (0 != file_path->Length) && (NULL != file_path->Buffer)); if ((NULL == file_path) || (0 == file_path->Length) || (NULL == file_path->Buffer)) { return INVALID_UCHAR; } // Lets check for explicit r/w pipe names if (0 == RtlCompareUnicodeString(file_path, &bulk_read_pipe_name, TRUE)) return bulk_read_pipe_index(); if (0 == RtlCompareUnicodeString(file_path, &bulk_write_pipe_name, TRUE)) return bulk_write_pipe_index(); // Lets check path format if (file_path->Length <= index_pipe_prefix.Length) { GoogleDbgPrint("\n!!!!! Bad format for pipe name: %wZ", file_path); return INVALID_UCHAR; } // Now when whe know that file_path->Length is sufficient lets match this // path with the prefix UNICODE_STRING prefix_match = *file_path; prefix_match.Length = index_pipe_prefix.Length; prefix_match.MaximumLength = prefix_match.Length; if (0 != RtlCompareUnicodeString(&prefix_match, &index_pipe_prefix, TRUE)) { GoogleDbgPrint("\n!!!!! Bad format for pipe name: %wZ", file_path); return INVALID_UCHAR; } // Prefix matches. Make sure that remaining chars are all decimal digits. // Pipe index begins right after the prefix ends. const ULONG index_begins_at = WcharLen(index_pipe_prefix.Length); const ULONG name_len = WcharLen(file_path->Length); for (ULONG index = index_begins_at; index < name_len; index++) { if ((file_path->Buffer[index] > L'9') || (file_path->Buffer[index] < L'0')) { GoogleDbgPrint("\n!!!!! Bad format for pipe name: %wZ", file_path); return INVALID_UCHAR; } } // Parse the pipe# ULONG uval = 0; ULONG umultiplier = 1; // traversing least to most significant digits. for (ULONG index = name_len - 1; index >= index_begins_at; index--) { uval += (umultiplier * static_cast<ULONG>(file_path->Buffer[index] - L'0')); umultiplier *= 10; } return static_cast<UCHAR>(uval); }
PFFS_MCB FFSSearchMcb( PFFS_VCB Vcb, PFFS_MCB Parent, PUNICODE_STRING FileName) { PFFS_MCB TmpMcb = Parent->Child; while (TmpMcb) { if (!RtlCompareUnicodeString( &(TmpMcb->ShortName), FileName, TRUE)) break; TmpMcb = TmpMcb->Next; } if (TmpMcb) { FFSRefreshMcb(Vcb, TmpMcb); } return TmpMcb; }
/// <summary> /// Get address of a system module /// Either 'pName' or 'pAddress' is required to perform search /// </summary> /// <param name="pName">Base name of the image (e.g. hal.dll)</param> /// <param name="pAddress">Address inside module</param> /// <returns>Found loader entry. NULL if nothing found</returns> PKLDR_DATA_TABLE_ENTRY BBGetSystemModule( IN PUNICODE_STRING pName, IN PVOID pAddress ) { ASSERT( (pName != NULL || pAddress != NULL) && PsLoadedModuleList != NULL ); if ((pName == NULL && pAddress == NULL) || PsLoadedModuleList == NULL) return NULL; // No images if (IsListEmpty( PsLoadedModuleList )) return NULL; // Search in PsLoadedModuleList for (PLIST_ENTRY pListEntry = PsLoadedModuleList->Flink; pListEntry != PsLoadedModuleList; pListEntry = pListEntry->Flink) { PKLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD( pListEntry, KLDR_DATA_TABLE_ENTRY, InLoadOrderLinks ); // Check by name or by address if ((pName && RtlCompareUnicodeString( &pEntry->BaseDllName, pName, FALSE ) == 0) || (pAddress && pAddress >= pEntry->DllBase && (PUCHAR)pAddress < (PUCHAR)pEntry->DllBase + pEntry->SizeOfImage)) { return pEntry; } } return NULL; }
PNPFS_FCB NpfsFindPipe(PNPFS_VCB Vcb, PUNICODE_STRING PipeName) { PLIST_ENTRY CurrentEntry; PNPFS_FCB Fcb; CurrentEntry = Vcb->PipeListHead.Flink; while (CurrentEntry != &Vcb->PipeListHead) { Fcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB, PipeListEntry); if (RtlCompareUnicodeString(PipeName, &Fcb->PipeName, TRUE) == 0) { DPRINT("<%wZ> = <%wZ>\n", PipeName, &Fcb->PipeName); (VOID)InterlockedIncrement(&Fcb->RefCount); return Fcb; } CurrentEntry = CurrentEntry->Flink; } return NULL; }
__inline LONG FsRtlCompareNodeAndKey ( TUNNEL_NODE *Node, ULONGLONG DirectoryKey, PUNICODE_STRING Name ) /*++ Routine Description: Compare a tunnel node with a key/name pair Arguments: Node - a tunnel node DirectoryKey - a key value Name - a filename Return Value: Signed comparison result --*/ { return (Node->DirKey > DirectoryKey ? 1 : (Node->DirKey < DirectoryKey ? -1 : RtlCompareUnicodeString((FlagOn(Node->Flags, TUNNEL_FLAG_KEY_SHORT) ? &Node->ShortName : &Node->LongName), Name, TRUE))); }
PADAPTER_BINDING NTAPI LocateAdapterBindingByName(IN PPROTOCOL_BINDING ProtocolBinding, IN PNDIS_STRING AdapterName) { PLIST_ENTRY CurrentEntry; PADAPTER_BINDING AdapterBinding; KIRQL OldIrql; KeAcquireSpinLock(&ProtocolBinding->Lock, &OldIrql); CurrentEntry = ProtocolBinding->AdapterListHead.Flink; while (CurrentEntry != &ProtocolBinding->AdapterListHead) { AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, ProtocolListEntry); if (RtlCompareUnicodeString(AdapterName, &AdapterBinding->Adapter->NdisMiniportBlock.MiniportName, TRUE) == 0) { KeReleaseSpinLock(&ProtocolBinding->Lock, OldIrql); return AdapterBinding; } CurrentEntry = CurrentEntry->Flink; } KeReleaseSpinLock(&ProtocolBinding->Lock, OldIrql); return NULL; }
NTSTATUS DispatchCreate( PDEVICE_OBJECT fdo, PIRP Irp ) { PIO_STACK_LOCATION stack; PDEVICE_EXTENSION pdx; UNICODE_STRING interfaceName; NTSTATUS status; pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; stack = IoGetCurrentIrpStackLocation( Irp ); status = STATUS_SUCCESS; RtlInitUnicodeString( &interfaceName, OperationInterfaceFile ); if(0 == RtlCompareUnicodeString( &interfaceName, &stack->FileObject->FileName, TRUE)) { // we allow only exclusive access to the device if(InterlockedIncrement(&pdx->handles) != 1) { InterlockedDecrement( &pdx->handles ); status = STATUS_ACCESS_DENIED; KdPrint((DRIVERNAME " - ACCESS DENIED\n")); } } return CompleteRequest( Irp, status, 0 ); }
STDCALL int RtlEqualUnicodeString(const struct ustring *s1, const struct ustring *s2, int CaseInsensitive ) { if (s1->len != s2->len) return 0; return !RtlCompareUnicodeString(s1, s2, CaseInsensitive); }
BOOLEAN removeDenyFilePath(PVOID pNode1, PVOID pNode2) { if ( RtlCompareUnicodeString ((PUNICODE_STRING)pNode1, (PUNICODE_STRING)pNode2, TRUE) == 0 ) { BDKitFreePool(pNode1); return TRUE; } return FALSE; }
/* * @implemented */ VOID DeleteSymbolicLinkNameFromMemory(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLink, IN BOOLEAN MarkOffline) { PLIST_ENTRY DeviceEntry, SymbolEntry; PDEVICE_INFORMATION DeviceInformation; PSYMLINK_INFORMATION SymlinkInformation; /* First of all, ensure we have devices */ if (IsListEmpty(&(DeviceExtension->DeviceListHead))) { return; } /* Then, look for the symbolic name */ for (DeviceEntry = DeviceExtension->DeviceListHead.Flink; DeviceEntry != &(DeviceExtension->DeviceListHead); DeviceEntry = DeviceEntry->Flink) { DeviceInformation = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry); for (SymbolEntry = DeviceInformation->SymbolicLinksListHead.Flink; SymbolEntry != &(DeviceInformation->SymbolicLinksListHead); SymbolEntry = SymbolEntry->Flink) { SymlinkInformation = CONTAINING_RECORD(SymbolEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry); /* One we have found it */ if (RtlCompareUnicodeString(SymbolicLink, &(SymlinkInformation->Name), TRUE) == 0) { /* Check if caller just want it to be offline */ if (MarkOffline) { SymlinkInformation->Online = FALSE; } else { /* If not, delete it & notify */ SendLinkDeleted(&(DeviceInformation->SymbolicName), SymbolicLink); RemoveEntryList(&(SymlinkInformation->SymbolicLinksListEntry)); FreePool(SymlinkInformation->Name.Buffer); FreePool(SymlinkInformation); } /* No need to go farther */ return; } } } return; }
static PALIAS_ENTRY IntGetAliasEntry(PCONSRV_CONSOLE Console, PALIAS_HEADER Header, PVOID Source, USHORT SourceLength, BOOLEAN Unicode) { UNICODE_STRING SourceU; PALIAS_ENTRY Entry; INT Diff; if (Header == NULL || Source == NULL) return NULL; if (Unicode) { SourceU.Buffer = Source; /* Length is in bytes */ SourceU.MaximumLength = SourceLength; } else { if (!ConvertInputAnsiToUnicode(Console, Source, SourceLength, &SourceU.Buffer, &SourceU.MaximumLength)) { return NULL; } } SourceU.Length = SourceU.MaximumLength; Entry = Header->Data; while (Entry) { Diff = RtlCompareUnicodeString(&Entry->Source, &SourceU, TRUE); if (!Diff) { if (!Unicode) ConsoleFreeHeap(SourceU.Buffer); return Entry; } if (Diff > 0) break; Entry = Entry->Next; } if (!Unicode) ConsoleFreeHeap(SourceU.Buffer); return NULL; }
static PALIAS_HEADER IntFindAliasHeader(PCONSRV_CONSOLE Console, PVOID ExeName, USHORT ExeLength, BOOLEAN UnicodeExe) { UNICODE_STRING ExeNameU; PALIAS_HEADER RootHeader = Console->Aliases; INT Diff; if (ExeName == NULL) return NULL; if (UnicodeExe) { ExeNameU.Buffer = ExeName; /* Length is in bytes */ ExeNameU.MaximumLength = ExeLength; } else { if (!ConvertInputAnsiToUnicode(Console, ExeName, ExeLength, &ExeNameU.Buffer, &ExeNameU.MaximumLength)) { return NULL; } } ExeNameU.Length = ExeNameU.MaximumLength; while (RootHeader) { Diff = RtlCompareUnicodeString(&RootHeader->ExeName, &ExeNameU, TRUE); if (!Diff) { if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer); return RootHeader; } if (Diff > 0) break; RootHeader = RootHeader->Next; } if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer); return NULL; }
NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp) { UNICODE_STRING interfaceName; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation( Irp ); RtlInitUnicodeString( &interfaceName, OperationInterfaceFile ); if(0 == RtlCompareUnicodeString( &interfaceName, &stack->FileObject->FileName, TRUE)) { InterlockedDecrement( &pdx->handles ); } KdPrint((DRIVERNAME " - handles after close: '%d'\n", pdx->handles)); return CompleteRequest( Irp, STATUS_SUCCESS, 0 ); }
static VOID IntInsertAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY NewEntry) { PALIAS_ENTRY CurrentEntry; PALIAS_ENTRY *LastLink = &Header->Data; INT Diff; while ((CurrentEntry = *LastLink) != NULL) { Diff = RtlCompareUnicodeString(&NewEntry->Source, &CurrentEntry->Source, TRUE); if (Diff < 0) break; LastLink = &CurrentEntry->Next; } *LastLink = NewEntry; NewEntry->Next = CurrentEntry; }
static VOID IntInsertAliasHeader(PALIAS_HEADER* RootHeader, PALIAS_HEADER NewHeader) { PALIAS_HEADER CurrentHeader; PALIAS_HEADER *LastLink = RootHeader; INT Diff; while ((CurrentHeader = *LastLink) != NULL) { Diff = RtlCompareUnicodeString(&NewHeader->ExeName, &CurrentHeader->ExeName, TRUE); if (Diff < 0) break; LastLink = &CurrentHeader->Next; } *LastLink = NewHeader; NewHeader->Next = CurrentHeader; }
/* * LockerCheckExtension * * Check if it matches any one of our static extension list */ BOOL LockerCheckExtension( __in PUNICODE_STRING Extension ) { const UNICODE_STRING *ext = LockerExtensionsToScan; if(Extension->Length == 0) { return FALSE; } while(ext->Buffer != NULL) { if(RtlCompareUnicodeString(Extension, ext, TRUE) == 0) { return TRUE; } ext++; } return FALSE; }
PFCB CdfsGrabFCBFromTable(PDEVICE_EXTENSION Vcb, PUNICODE_STRING FileName) { KIRQL oldIrql; PFCB Fcb; PLIST_ENTRY current_entry; KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql); if (FileName == NULL || FileName->Length == 0 || FileName->Buffer[0] == 0) { DPRINT("Return FCB for stream file object\n"); Fcb = Vcb->StreamFileObject->FsContext; Fcb->RefCount++; KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); return(Fcb); } current_entry = Vcb->FcbListHead.Flink; while (current_entry != &Vcb->FcbListHead) { Fcb = CONTAINING_RECORD(current_entry, FCB, FcbListEntry); DPRINT("Comparing '%wZ' and '%wZ'\n", FileName, &Fcb->PathName); if (RtlCompareUnicodeString(FileName, &Fcb->PathName, TRUE) == 0) { Fcb->RefCount++; KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); return(Fcb); } //FIXME: need to compare against short name in FCB here current_entry = current_entry->Flink; } KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); return(NULL); }
BOOLEAN CompareFileName(PUNICODE_STRING FileName, PINDEX_ENTRY_ATTRIBUTE IndexEntry, BOOLEAN DirSearch) { BOOLEAN Ret, Alloc = FALSE; UNICODE_STRING EntryName; EntryName.Buffer = IndexEntry->FileName.Name; EntryName.Length = EntryName.MaximumLength = IndexEntry->FileName.NameLength * sizeof(WCHAR); if (DirSearch) { UNICODE_STRING IntFileName; if (IndexEntry->FileName.NameType != NTFS_FILE_NAME_POSIX) { NT_VERIFY(NT_SUCCESS(RtlUpcaseUnicodeString(&IntFileName, FileName, TRUE))); Alloc = TRUE; } else { IntFileName = *FileName; } Ret = FsRtlIsNameInExpression(&IntFileName, &EntryName, (IndexEntry->FileName.NameType != NTFS_FILE_NAME_POSIX), NULL); if (Alloc) { RtlFreeUnicodeString(&IntFileName); } return Ret; } else { return (RtlCompareUnicodeString(FileName, &EntryName, (IndexEntry->FileName.NameType != NTFS_FILE_NAME_POSIX)) == 0); } }
RTL_GENERIC_COMPARE_RESULTS NTAPI ApphelpShimCacheCompareRoutine( _In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct) { PSHIM_CACHE_ENTRY FirstEntry = FirstStruct; PSHIM_CACHE_ENTRY SecondEntry = SecondStruct; LONG Result; Result = RtlCompareUnicodeString(&FirstEntry->Persistent.ImageName, &SecondEntry->Persistent.ImageName, TRUE); if (Result < 0) { return GenericLessThan; } else if (Result == 0) { return GenericEqual; } return GenericGreaterThan; }
static VOID NTAPI KernelModeTest(IN PVOID Context) { NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE ParentHandle, SystemRootHandle, TargetHandle; PFILE_OBJECT ParentFileObject, TargetFileObject, SystemRootFileObject; UNREFERENCED_PARAMETER(Context); /* Kernelmode mandatory for IoCreateFile */ ok(ExGetPreviousMode() == KernelMode, "UserMode returned!\n"); /* First of all, open \\SystemRoot * We're interested in 3 pieces of information about it: * -> Its target (it's a symlink): \Windows or \ReactOS * -> Its associated File Object * -> Its associated FCB */ TargetFileObject = NULL; IoStatusBlock.Status = 0xFFFFFFFF; TargetHandle = INVALID_HANDLE_VALUE; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRoot, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&TargetHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { Status = ObReferenceObjectByHandle(TargetHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&TargetFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); } ok(TargetFileObject != NULL, "Not target to continue!\n"); if (TargetFileObject == NULL) { if (TargetHandle != INVALID_HANDLE_VALUE) { ObCloseHandle(TargetHandle, KernelMode); } return; } /* Open target directory of \SystemRoot\Regedit.exe * This must lead to \SystemRoot opening */ IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRootRegedit, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { Status = ObReferenceObjectByHandle(ParentHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&ParentFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { /* At that point, file object must point to \SystemRoot * But must not be the same FO than target (diverted file object) * This means FCB & FileName are equal * But CCB & FO are different * CCB must be != NULL, otherwise it means open failed */ ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n"); ok_eq_pointer(ParentFileObject->RelatedFileObject, NULL); ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext); ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n"); ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n"); ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0); ObDereferenceObject(ParentFileObject); } /* Because target exists FSD must signal it */ ok_eq_long(IoStatusBlock.Information, FILE_EXISTS); ObCloseHandle(ParentHandle, KernelMode); } /* Do the same with relative open */ IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRoot, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&SystemRootHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &Regedit, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, SystemRootHandle, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { Status = ObReferenceObjectByHandle(ParentHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&ParentFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n"); ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext); ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n"); ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n"); ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0); Status = ObReferenceObjectByHandle(SystemRootHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&SystemRootFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { ok_eq_pointer(ParentFileObject->RelatedFileObject, SystemRootFileObject); ok(ParentFileObject->RelatedFileObject != TargetFileObject, "File objects must be different\n"); ok(SystemRootFileObject != TargetFileObject, "File objects must be different\n"); ObDereferenceObject(SystemRootFileObject); } ObDereferenceObject(ParentFileObject); } ok_eq_long(IoStatusBlock.Information, FILE_EXISTS); ObCloseHandle(ParentHandle, KernelMode); } ObCloseHandle(SystemRootHandle, KernelMode); } /* *** */ /* Now redo the same scheme, but using a target that doesn't exist * The difference will be in IoStatusBlock.Information, the FSD will * inform that the target doesn't exist. * Clear for rename :-) */ IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRootFoobar, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { Status = ObReferenceObjectByHandle(ParentHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&ParentFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n"); ok_eq_pointer(ParentFileObject->RelatedFileObject, NULL); ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext); ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n"); ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n"); ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0); ObDereferenceObject(ParentFileObject); } ok_eq_long(IoStatusBlock.Information, FILE_DOES_NOT_EXIST); ObCloseHandle(ParentHandle, KernelMode); } IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRoot, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&SystemRootHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &Foobar, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, SystemRootHandle, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { Status = ObReferenceObjectByHandle(ParentHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&ParentFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n"); ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext); ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n"); ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n"); ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0); Status = ObReferenceObjectByHandle(SystemRootHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&SystemRootFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { ok_eq_pointer(ParentFileObject->RelatedFileObject, SystemRootFileObject); ok(ParentFileObject->RelatedFileObject != TargetFileObject, "File objects must be different\n"); ok(SystemRootFileObject != TargetFileObject, "File objects must be different\n"); ObDereferenceObject(SystemRootFileObject); } ObDereferenceObject(ParentFileObject); } ok_eq_long(IoStatusBlock.Information, FILE_DOES_NOT_EXIST); ObCloseHandle(ParentHandle, KernelMode); } ObCloseHandle(SystemRootHandle, KernelMode); } ObDereferenceObject(TargetFileObject); ObCloseHandle(TargetHandle, KernelMode); /* *** */ /* Direct target open of something that doesn't exist */ IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRootFoobarFoobar, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_OBJECT_PATH_NOT_FOUND); ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF); if (Status == STATUS_SUCCESS) { ObCloseHandle(ParentHandle, KernelMode); } /* Relative target open of something that doesn't exist */ IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRoot, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&SystemRootHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &FoobarFoobar, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, SystemRootHandle, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_OBJECT_PATH_NOT_FOUND); ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF); if (Status == STATUS_SUCCESS) { ObCloseHandle(ParentHandle, KernelMode); } ObCloseHandle(SystemRootHandle, KernelMode); } }
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; }
static BOOLEAN IsAcpiComputer(VOID) { UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"); UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); UNICODE_STRING AcpiBiosIdentifier = RTL_CONSTANT_STRING(L"ACPI BIOS"); OBJECT_ATTRIBUTES ObjectAttributes; PKEY_BASIC_INFORMATION pDeviceInformation = NULL; ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR); PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL; ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR); ULONG RequiredSize; ULONG IndexDevice = 0; UNICODE_STRING DeviceName, ValueName; HANDLE hDevicesKey = NULL; HANDLE hDeviceKey = NULL; NTSTATUS Status; BOOLEAN ret = FALSE; InitializeObjectAttributes(&ObjectAttributes, &MultiKeyPathU, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&hDevicesKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status); goto cleanup; } pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength); if (!pDeviceInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength); if (!pDeviceInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } while (TRUE) { Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); if (Status == STATUS_NO_MORE_ENTRIES) break; else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) { RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation); DeviceInfoLength = RequiredSize; pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength); if (!pDeviceInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize); } if (!NT_SUCCESS(Status)) { DPRINT("NtEnumerateKey() failed with status 0x%08lx\n", Status); goto cleanup; } IndexDevice++; /* Open device key */ DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength; DeviceName.Buffer = pDeviceInformation->Name; InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_CASE_INSENSITIVE, hDevicesKey, NULL); Status = NtOpenKey( &hDeviceKey, KEY_QUERY_VALUE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status); goto cleanup; } /* Read identifier */ Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) { RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation); ValueInfoLength = RequiredSize; pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength); if (!pValueInformation) { DPRINT("RtlAllocateHeap() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize); } if (!NT_SUCCESS(Status)) { DPRINT("NtQueryValueKey() failed with status 0x%08lx\n", Status); goto nextdevice; } else if (pValueInformation->Type != REG_SZ) { DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ); goto nextdevice; } ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength; ValueName.Buffer = (PWCHAR)pValueInformation->Data; if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL) ValueName.Length -= sizeof(WCHAR); if (RtlCompareUnicodeString(&ValueName, &AcpiBiosIdentifier, FALSE) == 0) { DPRINT("Found ACPI BIOS\n"); ret = TRUE; goto cleanup; } nextdevice: NtClose(hDeviceKey); hDeviceKey = NULL; } cleanup: if (pDeviceInformation) RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation); if (pValueInformation) RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation); if (hDevicesKey) NtClose(hDevicesKey); if (hDeviceKey) NtClose(hDeviceKey); return ret; }
/// <summary> /// Get module base address by name /// </summary> /// <param name="pProcess">Target process</param> /// <param name="ModuleName">Nodule name to search for</param> /// <param name="isWow64">If TRUE - search in 32-bit PEB</param> /// <returns>Found address, NULL if not found</returns> PVOID BBGetUserModule( IN PEPROCESS pProcess, IN PUNICODE_STRING ModuleName, IN BOOLEAN isWow64 ) { ASSERT( pProcess != NULL ); if (pProcess == NULL) return NULL; // Protect from UserMode AV __try { LARGE_INTEGER time = { 0 }; time.QuadPart = -250ll * 10 * 1000; // 250 msec. // Wow64 process if (isWow64) { PPEB32 pPeb32 = (PPEB32)PsGetProcessWow64Process( pProcess ); if (pPeb32 == NULL) { DPRINT( "BlackBone: %s: No PEB present. Aborting\n", __FUNCTION__ ); return NULL; } // Wait for loader a bit for (INT i = 0; !pPeb32->Ldr && i < 10; i++) { DPRINT( "BlackBone: %s: Loader not intialiezd, waiting\n", __FUNCTION__ ); KeDelayExecutionThread( KernelMode, TRUE, &time ); } // Still no loader if (!pPeb32->Ldr) { DPRINT( "BlackBone: %s: Loader was not intialiezd in time. Aborting\n", __FUNCTION__ ); return NULL; } // Search in InLoadOrderModuleList for (PLIST_ENTRY32 pListEntry = (PLIST_ENTRY32)((PPEB_LDR_DATA32)pPeb32->Ldr)->InLoadOrderModuleList.Flink; pListEntry != &((PPEB_LDR_DATA32)pPeb32->Ldr)->InLoadOrderModuleList; pListEntry = (PLIST_ENTRY32)pListEntry->Flink) { UNICODE_STRING ustr; PLDR_DATA_TABLE_ENTRY32 pEntry = CONTAINING_RECORD( pListEntry, LDR_DATA_TABLE_ENTRY32, InLoadOrderLinks ); RtlUnicodeStringInit( &ustr, (PWCH)pEntry->BaseDllName.Buffer ); if (RtlCompareUnicodeString( &ustr, ModuleName, TRUE ) == 0) return (PVOID)pEntry->DllBase; } } // Native process else { PPEB pPeb = PsGetProcessPeb( pProcess ); if (!pPeb) { DPRINT( "BlackBone: %s: No PEB present. Aborting\n", __FUNCTION__ ); return NULL; } // Wait for loader a bit for (INT i = 0; !pPeb->Ldr && i < 10; i++) { DPRINT( "BlackBone: %s: Loader not intialiezd, waiting\n", __FUNCTION__ ); KeDelayExecutionThread( KernelMode, TRUE, &time ); } // Still no loader if (!pPeb->Ldr) { DPRINT( "BlackBone: %s: Loader was not intialiezd in time. Aborting\n", __FUNCTION__ ); return NULL; } // Search in InLoadOrderModuleList for (PLIST_ENTRY pListEntry = pPeb->Ldr->InLoadOrderModuleList.Flink; pListEntry != &pPeb->Ldr->InLoadOrderModuleList; pListEntry = pListEntry->Flink) { PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD( pListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks ); if (RtlCompareUnicodeString( &pEntry->BaseDllName, ModuleName, TRUE ) == 0) return pEntry->DllBase; } } } __except (EXCEPTION_EXECUTE_HANDLER) { DPRINT( "BlackBone: %s: Exception, Code: 0x%X\n", __FUNCTION__, GetExceptionCode() ); } return NULL; }
NTSTATUS AFSRDRDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp); PFILE_OBJECT pFileObject = pIrpSp->FileObject; BOOLEAN bCompleteIrp = TRUE; __Enter { switch( pIrpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_REDIR_QUERY_PATH: { QUERY_PATH_REQUEST *pPathRequest = (QUERY_PATH_REQUEST *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer; UNICODE_STRING uniPathName; ntStatus = STATUS_BAD_NETWORK_PATH; uniPathName.Length = (USHORT)pPathRequest->PathNameLength; uniPathName.MaximumLength = uniPathName.Length; uniPathName.Buffer = pPathRequest->FilePathName; if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR)) { USHORT usLength = uniPathName.Length; uniPathName.Length = AFSServerName.Length; // // Skip over the first slash in the name // uniPathName.Buffer = &uniPathName.Buffer[ 1]; // // Check to see if the first (or only) component // of the path matches the server name // if( RtlCompareUnicodeString( &AFSServerName, &uniPathName, TRUE) == 0 && ( usLength == AFSServerName.Length + sizeof( WCHAR) || uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\')) { ntStatus = STATUS_SUCCESS; pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR); } } break; } case IOCTL_REDIR_QUERY_PATH_EX: { QUERY_PATH_REQUEST_EX *pPathRequest = (QUERY_PATH_REQUEST_EX *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer; UNICODE_STRING uniPathName; ntStatus = STATUS_BAD_NETWORK_PATH; uniPathName.Length = pPathRequest->PathName.Length; uniPathName.MaximumLength = uniPathName.Length; uniPathName.Buffer = pPathRequest->PathName.Buffer; if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR)) { USHORT usLength = uniPathName.Length; uniPathName.Length = AFSServerName.Length; // // Skip over the first slash in the name // uniPathName.Buffer = &uniPathName.Buffer[ 1]; // // Check to see if the first (or only) component // of the path matches the server name // if( RtlCompareUnicodeString( &AFSServerName, &uniPathName, TRUE) == 0 && ( usLength == AFSServerName.Length + sizeof( WCHAR) || uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\')) { ntStatus = STATUS_SUCCESS; pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR); } } break; } default: ntStatus = STATUS_INVALID_DEVICE_REQUEST; break; } if (bCompleteIrp) { // // Complete the request // AFSCompleteRequest( Irp, ntStatus); } } return ntStatus; }
NTSTATUS NewNtDeviceIoControlFile( __in HANDLE FileHandle, __in_opt HANDLE Event, __in_opt PIO_APC_ROUTINE ApcRoutine, __in_opt PVOID ApcContext, __out PIO_STATUS_BLOCK IoStatusBlock, __in ULONG IoControlCode, __in_opt PVOID InputBuffer, __in ULONG InputBufferLength, __out_opt PVOID OutputBuffer, __in ULONG OutputBufferLength ) { NTSTATUS retour,ntStatus; PFILE_OBJECT fileObject = NULL; ULONG retLen, ret; UNICODE_STRING *path_str = NULL; UNICODE_STRING afd;//=NULL; WCHAR deviceafd[] = L"\\Device\\Afd"; PAFD_SEND_INFO pAfdTcpInfo = InputBuffer; PAFD_SEND_INFO_UDP pAfdUdpSendtoInfo = InputBuffer; PAFD_RECV_INFO_UDP pAfdUdpRecvFromInfo = InputBuffer; ULONG dwLen = 0; PCHAR pBuf = NULL; int i=0, pid=0; ProcessInformation process; char buffer_net[2000]; char prot[10]; IO_STATUS_BLOCK iostatus; LARGE_INTEGER time; ULONG ppid = 0; PCHAR toto; UCHAR *name; PUNICODE_STRING temp_unicode, addr=NULL; ANSI_STRING ansi; PEPROCESS pep; TDI_REQUEST_QUERY_INFORMATION Request; char Address[128]; //Request = TDI_QUERY_ADDRESS_INFO; KeQuerySystemTime(&time); RtlZeroMemory(&buffer_net, sizeof(buffer_net)); RtlZeroMemory(&prot, sizeof(prot)); // NTDEVICEIOCONTROLFILE NtDeviceIoControlFile = Zdicf.NtFunc; RtlInitUnicodeString (&afd, deviceafd); retour = ((NTDEVICEIOCONTROLFILE) (OldNtDeviceIoControlFile)) (FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, IoControlCode, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength); if(IoControlCode != AFD_SEND && IoControlCode != AFD_RECV && IoControlCode != AFD_SENDTO && IoControlCode != AFD_RECVFROM) return retour; // ZwDeviceIoControlFile(FileHandle, // NULL,NULL, NULL, // &iostatus, // IOCTL_TDI_QUERY_INFORMATION, // TDI_QUERY_ADDRESS_INFO, 0,//sizeof(TDI_QUERY_ADDRESS_INFO), // &Address, sizeof(Address)); pid = (LONG)PsGetCurrentProcessId(); if(pid == (int)UserLandID) return retour; PsLookupProcessByProcessId((HANDLE)pid,&pep); toto = (PCHAR) pep; ppid = *((ULONG*)(toto+0x140)); // On recupere les 16 premiers bits du nom du process name = PsGetProcessImageFileName(pep); if(ExGetPreviousMode() == UserMode) { if(FileHandle != NULL) { ObReferenceObjectByHandle(FileHandle, 0, 0, KernelMode, &fileObject, NULL); if (fileObject) { ntStatus = ObQueryNameString(fileObject, (POBJECT_NAME_INFORMATION)path_str, 0, &retLen); path_str = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, retLen, 0); if (ntStatus == STATUS_INFO_LENGTH_MISMATCH) { if (path_str) { ntStatus = ObQueryNameString(fileObject, (POBJECT_NAME_INFORMATION)path_str, retLen, &retLen); if(RtlCompareUnicodeString(path_str,&afd,TRUE) == 0) { trace_net++; switch(IoControlCode) { case AFD_SEND: sprintf(prot,"tcp"); break; case AFD_RECV: sprintf(prot,"tcp"); break; case AFD_SENDTO: sprintf(prot,"udp"); break; case AFD_RECVFROM: sprintf(prot,"udp"); break; default: sprintf(prot,"not"); } // if(strcmp(prot, "udp") == 0) // { // DbgPrint("Taiele de l'address : %i \n", pAfdUdpSendtoInfo->SizeOfRemoteAddress); // temp_unicode = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, pAfdUdpSendtoInfo->SizeOfRemoteAddress, 0); // temp_unicode = (PUNICODE_STRING) pAfdUdpSendtoInfo->RemoteAddress; // DbgPrint("address : %wZ \n", &temp_unicode); //RtlCopyUnicodeString( addr, temp_unicode); //DbgPrint("addr 1 :%wZ\n" , addr); // } if(InputBufferLength > 0) sprintf(buffer_net, "audit(%I64d,%i) pid=%i name=%s ppid=%i { send } size=%i prot=%s return=%x endoftrace", time.QuadPart, trace_net,pid, name,ppid, InputBufferLength, prot, retour); if(OutputBufferLength > 0) sprintf(buffer_net, "audit(%I64d,%i) pid=%i name=%s ppid=%i { recv } size=%i prot=%s return=%x endoftrace", time.QuadPart, trace_net,pid, name, ppid, OutputBufferLength, prot, retour); //DbgPrint("%wZ \n", path_str); ZwWriteFile(handlenet, NULL, NULL, NULL, &iostatus, buffer_net, strlen(buffer_net), 0, NULL); ZwFlushBuffersFile(handlenet, &iostatus); } if(path_str) ExFreePoolWithTag(path_str, 0); } } ObDereferenceObject(fileObject); } } } // if(fileObject != NULL) // ObDereferenceObject(fileObject); return retour; }
VALUE_SEARCH_RETURN_TYPE NTAPI CmpFindValueByNameFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCUNICODE_STRING Name, OUT PCM_CACHED_VALUE **CachedValue, OUT ULONG *Index, OUT PCM_KEY_VALUE *Value, OUT BOOLEAN *ValueIsCached, OUT PHCELL_INDEX CellToRelease) { PHHIVE Hive; VALUE_SEARCH_RETURN_TYPE SearchResult = SearchFail; LONG Result; UNICODE_STRING SearchName; PCELL_DATA CellData; PCACHED_CHILD_LIST ChildList; PCM_KEY_VALUE KeyValue; BOOLEAN IndexIsCached; ULONG i = 0; HCELL_INDEX Cell = HCELL_NIL; PCM_KEY_NODE KeyNode; /* Set defaults */ *CellToRelease = HCELL_NIL; *Value = NULL; /* Get the hive and child list */ Hive = Kcb->KeyHive; ChildList = &Kcb->ValueCache; KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell); ChildList = (PCACHED_CHILD_LIST)&KeyNode->ValueList; /* Check if the child list has any entries */ if (ChildList->Count != 0) { /* Get the value list associated to this child list */ SearchResult = CmpGetValueListFromCache(Kcb, &CellData, &IndexIsCached, &Cell); if (SearchResult != SearchSuccess) { /* We either failed or need the exclusive lock */ ASSERT((SearchResult == SearchFail) || !(CmpIsKcbLockedExclusive(Kcb))); ASSERT(Cell == HCELL_NIL); return SearchResult; } /* The index shouldn't be cached right now */ if (IndexIsCached) ASSERT_VALUE_CACHE(); /* Loop every value */ while (TRUE) { /* Check if there's any cell to release */ if (*CellToRelease != HCELL_NIL) { /* Release it now */ HvReleaseCell(Hive, *CellToRelease); *CellToRelease = HCELL_NIL; } /* Get the key value for this index */ SearchResult = CmpGetValueKeyFromCache(Kcb, CellData, i, CachedValue, Value, IndexIsCached, ValueIsCached, CellToRelease); if (SearchResult != SearchSuccess) { /* We either failed or need the exclusive lock */ ASSERT((SearchResult == SearchFail) || !(CmpIsKcbLockedExclusive(Kcb))); ASSERT(Cell == HCELL_NIL); return SearchResult; } /* Check if the both the index and the value are cached */ if ((IndexIsCached) && (*ValueIsCached)) { /* We don't expect this yet */ ASSERT_VALUE_CACHE(); Result = -1; } else { /* No cache, so try to compare the name. Is it compressed? */ KeyValue = *Value; if (KeyValue->Flags & VALUE_COMP_NAME) { /* It is, do a compressed name comparison */ Result = CmpCompareCompressedName(Name, KeyValue->Name, KeyValue->NameLength); } else { /* It's not compressed, so do a standard comparison */ SearchName.Length = KeyValue->NameLength; SearchName.MaximumLength = SearchName.Length; SearchName.Buffer = KeyValue->Name; Result = RtlCompareUnicodeString(Name, &SearchName, TRUE); } } /* Check if we found the value data */ if (!Result) { /* We have, return the index of the value and success */ *Index = i; SearchResult = SearchSuccess; goto Quickie; } /* We didn't find it, try the next entry */ if (++i == ChildList->Count) { /* The entire list was parsed, fail */ *Value = NULL; SearchResult = SearchFail; goto Quickie; } } } /* We should only get here if the child list is empty */ ASSERT(ChildList->Count == 0); Quickie: /* Release the value list cell if required, and return search result */ if (Cell != HCELL_NIL) HvReleaseCell(Hive, Cell); return SearchResult; }
static VOID NTAPI TestSymlinks(VOID) { HANDLE ReparseHandle; NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; PREPARSE_DATA_BUFFER Reparse; FILE_DISPOSITION_INFORMATION ToDelete; PFILE_OBJECT FileObject; UNICODE_STRING SysDir, Foobar, Regedit; ULONG Size; /* Get Windows/ReactOS directory */ InitializeObjectAttributes(&ObjectAttributes, &SystemRoot, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenFile(&ReparseHandle, FILE_READ_DATA, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_DIRECTORY_FILE); if (skip(NT_SUCCESS(Status), "Opening \\SystemRoot failed: %lx\n", Status)) { return; } Status = ObReferenceObjectByHandle(ReparseHandle, FILE_READ_DATA, *IoFileObjectType, UserMode, (PVOID *)&FileObject, NULL); if (skip(NT_SUCCESS(Status), "Querying name failed: %lx\n", Status)) { ZwClose(ReparseHandle); return; } SysDir.Buffer = ExAllocatePool(NonPagedPool, FileObject->FileName.Length + sizeof(L"\\??\\C:")); if (skip(SysDir.Buffer != NULL, "Allocating memory failed\n")) { ObDereferenceObject(FileObject); ZwClose(ReparseHandle); return; } SysDir.Length = sizeof(L"\\??\\C:") - sizeof(UNICODE_NULL); SysDir.MaximumLength = FileObject->FileName.Length + sizeof(L"\\??\\C:"); RtlCopyMemory(SysDir.Buffer, L"\\??\\C:", sizeof(L"\\??\\C:") - sizeof(UNICODE_NULL)); RtlAppendUnicodeStringToString(&SysDir, &FileObject->FileName); Foobar.Buffer = ExAllocatePool(NonPagedPool, FileObject->FileName.Length + sizeof(L"\\foobar.exe")); if (skip(Foobar.Buffer != NULL, "Allocating memory failed\n")) { ExFreePool(SysDir.Buffer); ObDereferenceObject(FileObject); ZwClose(ReparseHandle); return; } Foobar.Length = 0; Foobar.MaximumLength = FileObject->FileName.Length + sizeof(L"\\foobar.exe"); RtlCopyUnicodeString(&Foobar, &FileObject->FileName); RtlCopyMemory(&Foobar.Buffer[Foobar.Length / sizeof(WCHAR)], L"\\foobar.exe", sizeof(L"\\foobar.exe") - sizeof(UNICODE_NULL)); Foobar.Length += (sizeof(L"\\foobar.exe") - sizeof(UNICODE_NULL)); Regedit.Buffer = ExAllocatePool(NonPagedPool, FileObject->FileName.Length + sizeof(L"\\regedit.exe")); if (skip(Regedit.Buffer != NULL, "Allocating memory failed\n")) { ExFreePool(Foobar.Buffer); ExFreePool(SysDir.Buffer); ObDereferenceObject(FileObject); ZwClose(ReparseHandle); return; } Regedit.Length = 0; Regedit.MaximumLength = FileObject->FileName.Length + sizeof(L"\\regedit.exe"); RtlCopyUnicodeString(&Regedit, &FileObject->FileName); RtlCopyMemory(&Regedit.Buffer[Regedit.Length / sizeof(WCHAR)], L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL)); Regedit.Length += (sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL)); ObDereferenceObject(FileObject); ZwClose(ReparseHandle); ToDelete.DeleteFile = TRUE; Size = FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + SysDir.Length * 2 + sizeof(L"\\regedit.exe") * 2 - sizeof(L"\\??\\") - sizeof(UNICODE_NULL); InitializeObjectAttributes(&ObjectAttributes, &SystemRootFoobar, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwCreateFile(&ReparseHandle, GENERIC_READ | GENERIC_WRITE | DELETE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SUPERSEDE, FILE_NON_DIRECTORY_FILE, NULL, 0); ok_eq_hex(Status, STATUS_SUCCESS); if (skip(NT_SUCCESS(Status), "Creating file failed: %lx\n", Status)) { ExFreePool(Regedit.Buffer); ExFreePool(Foobar.Buffer); ExFreePool(SysDir.Buffer); return; } Reparse = ExAllocatePool(NonPagedPool, Size); RtlZeroMemory(Reparse, Size); Reparse->ReparseTag = IO_REPARSE_TAG_SYMLINK; Reparse->ReparseDataLength = 12 + SysDir.Length * 2 + sizeof(L"\\regedit.exe") * 2 - sizeof(L"\\??\\") - sizeof(UNICODE_NULL); Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength = SysDir.Length + sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL); Reparse->SymbolicLinkReparseBuffer.PrintNameLength = SysDir.Length + sizeof(L"\\regedit.exe") - sizeof(L"\\??\\"); Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset = Reparse->SymbolicLinkReparseBuffer.PrintNameLength; RtlCopyMemory(Reparse->SymbolicLinkReparseBuffer.PathBuffer, (WCHAR *)((ULONG_PTR)SysDir.Buffer + sizeof(L"\\??\\") - sizeof(UNICODE_NULL)), SysDir.Length - sizeof(L"\\??\\") + sizeof(UNICODE_NULL)); RtlCopyMemory((WCHAR *)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + SysDir.Length - sizeof(L"\\??\\") + sizeof(UNICODE_NULL)), L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL)); RtlCopyMemory((WCHAR *)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset), SysDir.Buffer, SysDir.Length); RtlCopyMemory((WCHAR *)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset + SysDir.Length), L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL)); Status = ZwFsControlFile(ReparseHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_SET_REPARSE_POINT, Reparse, Size, NULL, 0); ok_eq_hex(Status, STATUS_SUCCESS); if (!NT_SUCCESS(Status)) { ZwClose(ReparseHandle); Status = ZwCreateFile(&ReparseHandle, FILE_WRITE_ATTRIBUTES | DELETE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_SUPERSEDE, FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0); if (skip(NT_SUCCESS(Status), "Creating symlink failed: %lx\n", Status)) { Status = ZwOpenFile(&ReparseHandle, DELETE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE); ok_eq_hex(Status, STATUS_SUCCESS); ZwClose(ReparseHandle); ExFreePool(Regedit.Buffer); ExFreePool(Foobar.Buffer); ExFreePool(SysDir.Buffer); ExFreePool(Reparse); return; } Status = ZwFsControlFile(ReparseHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_SET_REPARSE_POINT, Reparse, Size, NULL, 0); } if (skip(NT_SUCCESS(Status), "Creating symlink failed: %lx\n", Status)) { ZwSetInformationFile(ReparseHandle, &IoStatusBlock, &ToDelete, sizeof(ToDelete), FileDispositionInformation); ZwClose(ReparseHandle); ExFreePool(Regedit.Buffer); ExFreePool(Foobar.Buffer); ExFreePool(SysDir.Buffer); ExFreePool(Reparse); return; } ZwClose(ReparseHandle); Status = ZwCreateFile(&ReparseHandle, GENERIC_READ, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0); ok(Status == STATUS_SUCCESS || /* Windows Vista+ */ Status == STATUS_IO_REPARSE_TAG_NOT_HANDLED, /* Windows 2003 (SP1, SP2) */ "ZwCreateFile returned unexpected status: %lx\n", Status); if (NT_SUCCESS(Status)) { Status = ObReferenceObjectByHandle(ReparseHandle, FILE_READ_DATA, *IoFileObjectType, UserMode, (PVOID *)&FileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (NT_SUCCESS(Status)) { ok(RtlCompareUnicodeString(&Regedit, &FileObject->FileName, TRUE) == 0, "Expected: %wZ. Opened: %wZ\n", &Regedit, &FileObject->FileName); ObDereferenceObject(FileObject); } ZwClose(ReparseHandle); } ExFreePool(Regedit.Buffer); Status = IoCreateFile(&ReparseHandle, GENERIC_READ, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING | IO_STOP_ON_SYMLINK); ok(Status == STATUS_STOPPED_ON_SYMLINK || /* Windows Vista+ */ Status == STATUS_IO_REPARSE_TAG_NOT_HANDLED, /* Windows 2003 (SP1, SP2) */ "ZwCreateFile returned unexpected status: %lx\n", Status); if (NT_SUCCESS(Status)) { ZwClose(ReparseHandle); } Status = ZwCreateFile(&ReparseHandle, GENERIC_READ | GENERIC_WRITE | DELETE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0); if (skip(NT_SUCCESS(Status), "Creating opening reparse point: %lx\n", Status)) { Status = ZwOpenFile(&ReparseHandle, DELETE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE); ok_eq_hex(Status, STATUS_SUCCESS); ZwClose(ReparseHandle); ExFreePool(Foobar.Buffer); ExFreePool(SysDir.Buffer); ExFreePool(Reparse); return; } Status = ObReferenceObjectByHandle(ReparseHandle, FILE_READ_DATA, *IoFileObjectType, UserMode, (PVOID *)&FileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (NT_SUCCESS(Status)) { ok(RtlCompareUnicodeString(&Foobar, &FileObject->FileName, TRUE) == 0, "Expected: %wZ. Opened: %wZ\n", &Foobar, &FileObject->FileName); ObDereferenceObject(FileObject); } ExFreePool(Foobar.Buffer); RtlZeroMemory(Reparse, Size); Status = ZwFsControlFile(ReparseHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_GET_REPARSE_POINT, NULL, 0, Reparse, Size); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Information, Size); if (NT_SUCCESS(Status)) { PWSTR Buffer; UNICODE_STRING ReparsePath, FullPath; ok_eq_hex(Reparse->ReparseTag, IO_REPARSE_TAG_SYMLINK); ok_eq_hex(Reparse->ReparseDataLength, 12 + SysDir.Length * 2 + sizeof(L"\\regedit.exe") * 2 - sizeof(L"\\??\\") - sizeof(UNICODE_NULL)); ok_eq_hex(Reparse->SymbolicLinkReparseBuffer.Flags, 0); FullPath.Length = 0; FullPath.MaximumLength = SysDir.Length + sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL); Buffer = FullPath.Buffer = ExAllocatePool(NonPagedPool, FullPath.MaximumLength); if (!skip(Buffer != NULL, "Memory allocation failed!\n")) { RtlCopyUnicodeString(&FullPath, &SysDir); RtlCopyMemory(&FullPath.Buffer[FullPath.Length / sizeof(WCHAR)], L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL)); FullPath.Length += (sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL)); ReparsePath.Buffer = (PWSTR)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset); ReparsePath.Length = ReparsePath.MaximumLength = Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength; ok(RtlCompareUnicodeString(&ReparsePath, &FullPath, TRUE) == 0, "Expected: %wZ. Got: %wZ\n", &ReparsePath, &FullPath); FullPath.Length -= (sizeof(L"\\??\\") - sizeof(UNICODE_NULL)); FullPath.MaximumLength -= (sizeof(L"\\??\\") - sizeof(UNICODE_NULL)); FullPath.Buffer = (PWSTR)((ULONG_PTR)Buffer + sizeof(L"\\??\\") - sizeof(UNICODE_NULL)); ReparsePath.Buffer = (PWSTR)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.PrintNameOffset); ReparsePath.Length = ReparsePath.MaximumLength = Reparse->SymbolicLinkReparseBuffer.PrintNameLength; ok(RtlCompareUnicodeString(&ReparsePath, &FullPath, TRUE) == 0, "Expected: %wZ. Got: %wZ\n", &ReparsePath, &FullPath); ExFreePool(Buffer); } } ExFreePool(SysDir.Buffer); ExFreePool(Reparse); ZwSetInformationFile(ReparseHandle, &IoStatusBlock, &ToDelete, sizeof(ToDelete), FileDispositionInformation); ZwClose(ReparseHandle); }
NTSTATUS UDFCompareVcb( IN PVCB OldVcb, IN PVCB NewVcb, IN BOOLEAN PhysicalOnly ) { NTSTATUS RC; UDF_FILE_INFO RootFileInfo; BOOLEAN SimpleLogicalCheck = FALSE; KdPrint(("UDFCompareVcb:\n")); if(UDFGlobalData.UDFFlags & UDF_DATA_FLAGS_BEING_UNLOADED) { KdPrint((" WRONG_VOLUME\n")); return STATUS_WRONG_VOLUME; } #define VCB_NE(x) (OldVcb->x != NewVcb->x) // compare physical parameters if(PhysicalOnly) { KdPrint((" PhysicalOnly\n")); if(VCB_NE(FirstLBA) || VCB_NE(LastLBA) || VCB_NE(FirstTrackNum) || VCB_NE(LastTrackNum) || VCB_NE(NWA) || VCB_NE(LastPossibleLBA) || VCB_NE(PhSerialNumber) || VCB_NE(PhErasable) || VCB_NE(PhDiskType) || VCB_NE(MediaClassEx) || /* We cannot compare these flags, because NewVcb is in unconditional ReadOnly */ /*((OldVcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) != (NewVcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)) || ((OldVcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) != (NewVcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY)) ||*/ VCB_NE(TargetDeviceObject) || // VCB_NE(xxx) || // VCB_NE(xxx) || VCB_NE(LastSession) ) { KdPrint((" WRONG_VOLUME (2)\n")); return STATUS_WRONG_VOLUME; } // Note, MRWStatus can change while media is mounted (stoppped/in-progress/complete) // We can compare only (Vcb->MRWStatus == 0) values if((OldVcb->MRWStatus == 0) != (NewVcb->MRWStatus == 0)) { KdPrint((" WRONG_VOLUME (4), missmatch MRW status\n")); } for(uint32 i=OldVcb->FirstTrackNum; i<=OldVcb->LastTrackNum; i++) { if(VCB_NE(TrackMap[i].FirstLba) || VCB_NE(TrackMap[i].LastLba) || VCB_NE(TrackMap[i].PacketSize) || VCB_NE(TrackMap[i].TrackParam) || VCB_NE(TrackMap[i].DataParam) || VCB_NE(TrackMap[i].NWA_V) ) { KdPrint((" WRONG_VOLUME (3), missmatch trk %d\n", i)); return STATUS_WRONG_VOLUME; } } KdPrint((" Vcb compare Ok\n")); return STATUS_SUCCESS; } // Something is nasty!!! We perform verify for not flushed volume // This should never happen, but some devices/buses and their drivers // can lead us to such condition. For example with help of RESET. // Now, we hope, that nobody changed media. // We shall make simplified logical structure check if(OldVcb->Modified) { KdPrint((" Vcb SIMPLE compare on !!!MODIFIED!!! volume\n")); ASSERT(FALSE); SimpleLogicalCheck = TRUE; } // compare logical structure if(!SimpleLogicalCheck && (OldVcb->InitVatCount != NewVcb->InitVatCount)) { KdPrint((" InitVatCount %d != %d \n", OldVcb->InitVatCount, NewVcb->InitVatCount)); return STATUS_WRONG_VOLUME; } // Compare volume creation time if(OldVcb->VolCreationTime != NewVcb->VolCreationTime) { KdPrint((" VolCreationTime %I64x != %I64x \n", OldVcb->VolCreationTime, NewVcb->VolCreationTime)); return STATUS_WRONG_VOLUME; } // Compare serial numbers if(OldVcb->SerialNumber != NewVcb->SerialNumber) { KdPrint((" SerialNumber %x != %x \n", OldVcb->SerialNumber, NewVcb->SerialNumber)); return STATUS_WRONG_VOLUME; } // Compare volume idents if(!SimpleLogicalCheck && RtlCompareUnicodeString(&(OldVcb->VolIdent),&(NewVcb->VolIdent),FALSE)) { KdPrint((" VolIdent missmatch \n")); return STATUS_WRONG_VOLUME; } if(SimpleLogicalCheck) { // do not touch RootDir. It can be partially recorded KdPrint((" SimpleLogicalCheck Ok\n")); return STATUS_SUCCESS; } RC = UDFOpenRootFile__(NewVcb, &(NewVcb->RootLbAddr), &RootFileInfo); if(!NT_SUCCESS(RC)) { KdPrint((" Can't open root file, status %x\n", RC)); UDFCleanUpFile__(NewVcb, &RootFileInfo); return STATUS_WRONG_VOLUME; } // perform exhaustive check if(!(OldVcb->RootDirFCB)) { KdPrint((" !(OldVcb->RootDirFCB)\n")); wr_vol: UDFCloseFile__(NewVcb, &RootFileInfo); UDFCleanUpFile__(NewVcb, &RootFileInfo); return STATUS_WRONG_VOLUME; } if(!UDFCompareFileInfo(&RootFileInfo, OldVcb->RootDirFCB->FileInfo)) { KdPrint((" !UDFCompareFileInfo\n")); goto wr_vol; } UDFCloseFile__(NewVcb, &RootFileInfo); UDFCleanUpFile__(NewVcb, &RootFileInfo); KdPrint(("UDFCompareVcb: Ok\n")); return STATUS_SUCCESS; #undef VCB_NE } // end UDFCompareVcb()
BOOLEAN NTAPI CmpFindNameInList(IN PHHIVE Hive, IN PCHILD_LIST ChildList, IN PUNICODE_STRING Name, IN PULONG ChildIndex, IN PHCELL_INDEX CellIndex) { PCELL_DATA CellData; HCELL_INDEX CellToRelease = HCELL_NIL; ULONG i; PCM_KEY_VALUE KeyValue; LONG Result; UNICODE_STRING SearchName; BOOLEAN Success; /* Make sure there's actually something on the list */ if (ChildList->Count != 0) { /* Get the cell data */ CellData = (PCELL_DATA)HvGetCell(Hive, ChildList->List); if (!CellData) { /* Couldn't get the cell... tell the caller */ *CellIndex = HCELL_NIL; return FALSE; } /* Now loop every entry */ for (i = 0; i < ChildList->Count; i++) { /* Check if we have a cell to release */ if (CellToRelease != HCELL_NIL) { /* Release it */ HvReleaseCell(Hive, CellToRelease); CellToRelease = HCELL_NIL; } /* Get this value */ KeyValue = (PCM_KEY_VALUE)HvGetCell(Hive, CellData->u.KeyList[i]); if (!KeyValue) { /* Return with no data found */ *CellIndex = HCELL_NIL; Success = FALSE; goto Return; } /* Save the cell to release */ CellToRelease = CellData->u.KeyList[i]; /* Check if it's a compressed value name */ if (KeyValue->Flags & VALUE_COMP_NAME) { /* Use the compressed name check */ Result = CmpCompareCompressedName(Name, KeyValue->Name, KeyValue->NameLength); } else { /* Setup the Unicode string */ SearchName.Length = KeyValue->NameLength; SearchName.MaximumLength = SearchName.Length; SearchName.Buffer = KeyValue->Name; Result = RtlCompareUnicodeString(Name, &SearchName, TRUE); } /* Check if we found it */ if (!Result) { /* We did...return info to caller */ if (ChildIndex) *ChildIndex = i; *CellIndex = CellData->u.KeyList[i]; /* Set success state */ Success = TRUE; goto Return; } } /* Got to the end of the list */ if (ChildIndex) *ChildIndex = i; *CellIndex = HCELL_NIL; /* Nothing found if we got here */ Success = TRUE; goto Return; } /* Nothing found...check if the caller wanted more info */ ASSERT(ChildList->Count == 0); if (ChildIndex) *ChildIndex = 0; *CellIndex = HCELL_NIL; /* Nothing found if we got here */ return TRUE; Return: /* Release the first cell we got */ if (CellData) HvReleaseCell(Hive, ChildList->List); /* Release the secondary one, if we have one */ if (CellToRelease) HvReleaseCell(Hive, CellToRelease); return Success; }