NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject) { KdPrint(("CreateDevice begin\n")); NTSTATUS status; //设备对象 指针 PDEVICE_OBJECT pDevObj; //设备对象扩展结构 指针 PDEVICE_EXTENSION pDevExt; //设备名称 UNICODE_STRING devName; RtlInitUnicodeString(&devName,DRIVER_NAME); //创建设备 status = IoCreateDevice( pDriverObject, //驱动对象 sizeof(DEVICE_EXTENSION), //设备扩展结构大小 &(UNICODE_STRING)devName, //设备名 或 NULL FILE_DEVICE_UNKNOWN, //设备类型 FILE_DEVICE_UNKNOWN 未知虚拟设备,且为独占(既只能被一个应用程序使用) 0, TRUE, &pDevObj ); //设备地址 out if (!NT_SUCCESS(status)) return status; //以直接的方式读写(既不使用缓冲区) pDevObj->Flags |= DO_DIRECT_IO; //填充扩展结构数据 pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; pDevExt->pDevice = pDevObj; //申请内存 保存设备名 ULONG length=wcslen(DRIVER_NAME)*sizeof(WCHAR); pDevExt->ustrDeviceName.Buffer=(PWCH)ExAllocatePool(PagedPool,length); pDevExt->ustrDeviceName.Length=pDevExt->ustrDeviceName.MaximumLength=length; RtlCopyUnicodeString(&pDevExt->ustrDeviceName,&devName); //符号链接名 UNICODE_STRING symLinkName; RtlInitUnicodeString(&symLinkName,DRIVER_LINK_NAME); //创建符号链接 pDevExt->ustrSymLinkName = symLinkName; status = IoCreateSymbolicLink( &symLinkName,&devName ); if (!NT_SUCCESS(status)) { IoDeleteDevice( pDevObj ); return status; } //申请内存 保存 符号链接名 length=wcslen(DRIVER_LINK_NAME)*sizeof(WCHAR); pDevExt->ustrSymLinkName.Buffer=(PWCH)ExAllocatePool(PagedPool,length); pDevExt->ustrSymLinkName.Length=pDevExt->ustrSymLinkName.MaximumLength=length; RtlCopyUnicodeString(&pDevExt->ustrSymLinkName,&symLinkName); KdPrint(("CreateDevice sucess and end\n")); return STATUS_SUCCESS; }
VOID KdbSymProcessSymbols( IN PLDR_DATA_TABLE_ENTRY LdrEntry) { if (!LoadSymbols) { LdrEntry->PatchInformation = NULL; return; } /* Remove symbol info if it already exists */ if (LdrEntry->PatchInformation) { KdbpSymRemoveCachedFile(LdrEntry->PatchInformation); } /* Error loading symbol info, try to load it from file */ KdbpSymLoadModuleSymbols(&LdrEntry->FullDllName, (PROSSYM_INFO*)&LdrEntry->PatchInformation); if (!LdrEntry->PatchInformation) { // HACK: module dll names don't identify the real files UNICODE_STRING SystemRoot; UNICODE_STRING ModuleNameCopy; RtlInitUnicodeString(&SystemRoot, L"\\SystemRoot\\System32\\Drivers\\"); ModuleNameCopy.Length = 0; ModuleNameCopy.MaximumLength = LdrEntry->BaseDllName.MaximumLength + SystemRoot.MaximumLength; ModuleNameCopy.Buffer = ExAllocatePool(NonPagedPool, SystemRoot.MaximumLength + LdrEntry->BaseDllName.MaximumLength); RtlCopyUnicodeString(&ModuleNameCopy, &SystemRoot); RtlCopyMemory (ModuleNameCopy.Buffer + ModuleNameCopy.Length / sizeof(WCHAR), LdrEntry->BaseDllName.Buffer, LdrEntry->BaseDllName.Length); ModuleNameCopy.Length += LdrEntry->BaseDllName.Length; KdbpSymLoadModuleSymbols(&ModuleNameCopy, (PROSSYM_INFO*)&LdrEntry->PatchInformation); if (!LdrEntry->PatchInformation) { SystemRoot.Length -= strlen("Drivers\\") * sizeof(WCHAR); RtlCopyUnicodeString(&ModuleNameCopy, &SystemRoot); RtlCopyMemory (ModuleNameCopy.Buffer + ModuleNameCopy.Length / sizeof(WCHAR), LdrEntry->BaseDllName.Buffer, LdrEntry->BaseDllName.Length); ModuleNameCopy.Length += LdrEntry->BaseDllName.Length; KdbpSymLoadModuleSymbols(&ModuleNameCopy, (PROSSYM_INFO*)&LdrEntry->PatchInformation); } RtlFreeUnicodeString(&ModuleNameCopy); } /* It already added symbols to cache */ DPRINT("Installed symbols: %wZ@%p-%p %p\n", &LdrEntry->BaseDllName, LdrEntry->DllBase, (PVOID)(LdrEntry->SizeOfImage + (ULONG_PTR)LdrEntry->DllBase), LdrEntry->PatchInformation); }
NTSTATUS DriverEntry(__in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath) { Bus_KdPrint(("Driver Entry\n")); ExInitializeNPagedLookasideList(&g_LookAside, NULL, NULL, 0, sizeof(PENDING_IRP), BUSENUM_POOL_TAG, 0); Globals.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); Globals.RegistryPath.Length = RegistryPath->Length; Globals.RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, Globals.RegistryPath.MaximumLength, BUSENUM_POOL_TAG); if (!Globals.RegistryPath.Buffer) { return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(&Globals.RegistryPath, RegistryPath); DriverObject->MajorFunction [IRP_MJ_CREATE ] = DriverObject->MajorFunction [IRP_MJ_CLOSE ] = Bus_CreateClose; DriverObject->MajorFunction [IRP_MJ_PNP ] = Bus_PnP; DriverObject->MajorFunction [IRP_MJ_POWER ] = Bus_Power; DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL ] = Bus_IoCtl; DriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] = Bus_Internal_IoCtl; DriverObject->DriverUnload = Bus_DriverUnload; DriverObject->DriverExtension->AddDevice = Bus_AddDevice; return STATUS_SUCCESS; }
/*! \brief Add a symbol file to the cache. * * \param FileName Filename of the symbol file. * \param RosSymInfo Pointer to the symbol info. * * \sa KdbpSymRemoveCachedFile */ static VOID KdbpSymAddCachedFile( IN PUNICODE_STRING FileName, IN PROSSYM_INFO RosSymInfo) { PIMAGE_SYMBOL_INFO_CACHE CacheEntry; KIRQL Irql; DPRINT("Adding symbol file: RosSymInfo = %p\n", RosSymInfo); /* allocate entry */ CacheEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof (IMAGE_SYMBOL_INFO_CACHE), TAG_KDBS); ASSERT(CacheEntry); RtlZeroMemory(CacheEntry, sizeof (IMAGE_SYMBOL_INFO_CACHE)); /* fill entry */ CacheEntry->FileName.Buffer = ExAllocatePoolWithTag(NonPagedPool, FileName->Length, TAG_KDBS); RtlCopyUnicodeString(&CacheEntry->FileName, FileName); ASSERT(CacheEntry->FileName.Buffer); CacheEntry->RefCount = 1; CacheEntry->RosSymInfo = RosSymInfo; KeAcquireSpinLock(&SymbolFileListLock, &Irql); InsertTailList(&SymbolFileListHead, &CacheEntry->ListEntry); KeReleaseSpinLock(&SymbolFileListLock, Irql); }
/*! \brief Add a symbol file to the cache. * * \param FileName Filename of the symbol file. * \param RosSymInfo Pointer to the symbol info. * * \sa KdbpSymRemoveCachedFile */ static VOID KdbpSymAddCachedFile( IN PUNICODE_STRING FileName, IN PROSSYM_INFO RosSymInfo) { PIMAGE_SYMBOL_INFO_CACHE CacheEntry; DPRINT("Adding symbol file: %wZ RosSymInfo = %p\n", FileName, RosSymInfo); /* allocate entry */ CacheEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof (IMAGE_SYMBOL_INFO_CACHE), TAG_KDBS); ASSERT(CacheEntry); RtlZeroMemory(CacheEntry, sizeof (IMAGE_SYMBOL_INFO_CACHE)); /* fill entry */ CacheEntry->FileName.Buffer = ExAllocatePoolWithTag(NonPagedPool, FileName->Length, TAG_KDBS); CacheEntry->FileName.MaximumLength = FileName->Length; RtlCopyUnicodeString(&CacheEntry->FileName, FileName); ASSERT(CacheEntry->FileName.Buffer); CacheEntry->RefCount = 1; CacheEntry->RosSymInfo = RosSymInfo; InsertTailList(&SymbolFileListHead, &CacheEntry->ListEntry); /* FIXME: Lock list? */ }
NTSTATUS ConstructDeviceName( IN PCWSTR Path, IN UCHAR Index, OUT PUNICODE_STRING DeviceName) { UNICODE_STRING UnicodePath; UNICODE_STRING UnicodeIndex; WCHAR IndexStringBuffer[5]; USHORT Size; USHORT LastCharacterIndex; /* Check for NULL parameters */ if ( ( ! Path ) || ( ! DeviceName ) ) { DPRINT("Unexpected NULL parameter"); return STATUS_INVALID_PARAMETER; } /* Range-check */ if ( Index >= SOUND_MAX_DEVICES ) { DPRINT("Device index %d out of range", Index); return STATUS_INVALID_PARAMETER; } /* Initialise the unicode path string */ RtlInitUnicodeString(&UnicodePath, Path); /* Calculate the length to hold the full string */ Size = UnicodePath.Length + sizeof(IndexStringBuffer) + sizeof(UNICODE_NULL); /* Allocate memory for DeviceName */ DeviceName->Buffer = ExAllocatePool(PagedPool, Size); DeviceName->MaximumLength = Size; if ( ! DeviceName->Buffer ) { DPRINT("Couldn't allocate memory for device name string"); return STATUS_INSUFFICIENT_RESOURCES; } /* Copy the path */ RtlCopyUnicodeString(DeviceName, &UnicodePath); /* Convert Index to string and append */ UnicodeIndex.Buffer = IndexStringBuffer; UnicodeIndex.MaximumLength = sizeof(IndexStringBuffer); RtlIntegerToUnicodeString((ULONG)Index, 10, &UnicodeIndex); RtlAppendUnicodeStringToString(DeviceName, &UnicodeIndex); /* Terminate the string */ LastCharacterIndex = DeviceName->Length / sizeof(UNICODE_NULL); DeviceName->Buffer[LastCharacterIndex] = UNICODE_NULL; return STATUS_SUCCESS; }
/*++ Routine Description: This routine updates the name of the target in the supplied stream handle context Arguments: DirectoryName - Supplies the directory name StreamHandleContext - Returns the updated name in the stream context Return Value: Status Note: The caller must synchronize access to the context. This routine does no synchronization --*/ NTSTATUS CtxUpdateNameInStreamHandleContext ( __in PUNICODE_STRING DirectoryName, __inout PCTX_STREAMHANDLE_CONTEXT StreamHandleContext ) { NTSTATUS status; PAGED_CODE(); // // Free any existing name // if (StreamHandleContext->FileName.Buffer != NULL) { CtxFreeUnicodeString(&StreamHandleContext->FileName); } // // Allocate and copy off the directory name // StreamHandleContext->FileName.MaximumLength = DirectoryName->Length; status = CtxAllocateUnicodeString(&StreamHandleContext->FileName); if (NT_SUCCESS(status)) { RtlCopyUnicodeString(&StreamHandleContext->FileName, DirectoryName); } return status; }
VOID Secondary_ChangeFcbFileName( IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PUNICODE_STRING FullFileName ) { RtlInitEmptyUnicodeString( &Fcb->FullFileName, Fcb->FullFileNameBuffer, sizeof(Fcb->FullFileNameBuffer) ); RtlCopyUnicodeString( &Fcb->FullFileName, FullFileName ); RtlInitEmptyUnicodeString( &Fcb->CaseInSensitiveFullFileName, Fcb->CaseInSensitiveFullFileNameBuffer, sizeof(Fcb->CaseInSensitiveFullFileNameBuffer) ); RtlDowncaseUnicodeString( &Fcb->CaseInSensitiveFullFileName, &Fcb->FullFileName, FALSE ); if (FullFileName->Length && FullFileName->Buffer[0] != L'\\') ASSERT( NDFAT_BUG ); return; }
NTSTATUS DriverEntry ( __in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath ) /*++ Routine Description: Initialize the driver dispatch table. Arguments: DriverObject - pointer to the driver object RegistryPath - pointer to a unicode string representing the path, to driver-specific key in the registry. Return Value: NT Status Code --*/ { Bus_KdPrint_Def (BUS_DBG_SS_TRACE, ("Driver Entry \n")); // // Save the RegistryPath for WMI. // Globals.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); Globals.RegistryPath.Length = RegistryPath->Length; Globals.RegistryPath.Buffer = ExAllocatePoolWithTag( PagedPool, Globals.RegistryPath.MaximumLength, BUSENUM_POOL_TAG ); if (!Globals.RegistryPath.Buffer) { return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(&Globals.RegistryPath, RegistryPath); // // Set entry points into the driver // DriverObject->MajorFunction [IRP_MJ_CREATE] = DriverObject->MajorFunction [IRP_MJ_CLOSE] = Bus_CreateClose; DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP; DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power; DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = Bus_IoCtl; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = Bus_SystemControl; DriverObject->DriverUnload = Bus_DriverUnload; DriverObject->DriverExtension->AddDevice = Bus_AddDevice; return STATUS_SUCCESS; }
NTSTATUS _NewVolumeEntry( _Out_ PVOLUME_ENTRY *VolumeEntry, _In_ PCUNICODE_STRING DosName, _In_ PCUNICODE_STRING DeviceName ) { PVOLUME_ENTRY newEntry = NULL; NTSTATUS status = STATUS_SUCCESS; if (VolumeEntry == NULL) { DBG_ERROR("VolumeEntry cannot be null.\n"); status = STATUS_INVALID_PARAMETER; goto Exit; } newEntry = (PVOLUME_ENTRY)MirAllocatePagedPool(sizeof(VOLUME_ENTRY)); if (newEntry == NULL) { DBG_ERROR_ALLOC_FAIL(newEntry, sizeof(VOLUME_ENTRY)); goto Exit; } InitializeListHead(&newEntry->MirrorList.ListHead); status = MirAllocateUnicodeString(&newEntry->DosName, DosName->Length); if (!NT_SUCCESS(status)) { DBG_ERROR_ALLOC_FAIL(newEntry->DosName, DosName->Length); MirFreePool(newEntry); goto Exit; } status = MirAllocateUnicodeString(&newEntry->DeviceName, DeviceName->Length); if (!NT_SUCCESS(status)) { DBG_ERROR_ALLOC_FAIL(newEntry->DeviceName, DeviceName->Length); MirFreeUnicodeString(&newEntry->DosName); MirFreePool(newEntry); goto Exit; } RtlCopyUnicodeString(&newEntry->DosName, DosName); RtlCopyUnicodeString(&newEntry->DeviceName, DeviceName); *VolumeEntry = newEntry; Exit: return status; }
// // 实现我们自己的AddDevice函数 // NTSTATUS myAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ) { if(gDeviceObject != NULL) { // 在这里面创建我们自己的设备对象,或者申请所需要的资源。 // 为了区分不同实例,将设备对象名构造成:”MyNdisDevice”+HardwareID。 UNICODE_STRING nameString; WCHAR wcsName[256]; UNICODE_STRING preName = RTL_CONSTANT_STRING(L"\\Device\\MyNdisDevice"); // 首先取得设备的HDID。 ULONG nameLength = 0; WCHAR wcsHardwareID[256]; //足够大了 NTSTATUS status = IoGetDeviceProperty (PhysicalDeviceObject, DevicePropertyHardwareID, 256, wcsHardwareID, &nameLength); if(status != STATUS_SUCCESS){ KdPrint(("Failed to get hardware ID %x\n", status)); return status; } // 下面构造设备对象的名字,根据上面的规则:“MyNdisDevice”+ HardwareID。 RtlInitEmptyUnicodeString( &nameString, wcsName, 256*2); RtlCopyUnicodeString( &nameString, &preName); //RtlUnicodeStringPrintf(&nameString, L"%wZ_%d_", &preName, 0); RtlAppendUnicodeToString( &nameString, wcsHardwareID); status = IoCreateDevice(DriverObject, 0, &nameString, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &gDeviceObject); // 如果创建失败了,我们有权利让函数以失败返回 // 但这样我们的驱动加载也就失败了 if(status != STATUS_SUCCESS){ KdPrint(("Failed to create device %ws\n", nameString)); return status; } } //ExAllocatePoolWithTag(); //申请资源及其他 // // 还可以加入其他正确的操作 // // 现在调用保存的Ndis库中的AddDevice实现 // 千万不要忘记,否则就会大错特错了 return systemAddDevice(DriverObject, PhysicalDeviceObject); }
NTSTATUS FltpGetObjectName(_In_ PVOID Object, _Inout_ PUNICODE_STRING ObjectName) { POBJECT_NAME_INFORMATION ObjectNameInfo = NULL; OBJECT_NAME_INFORMATION LocalNameInfo; ULONG ReturnLength; NTSTATUS Status; if (ObjectName == NULL) return STATUS_INVALID_PARAMETER; /* Get the size of the buffer required to hold the nameinfo */ Status = ObQueryNameString(Object, &LocalNameInfo, sizeof(LocalNameInfo), &ReturnLength); if (Status == STATUS_INFO_LENGTH_MISMATCH) { ObjectNameInfo = ExAllocatePoolWithTag(PagedPool, ReturnLength, FM_TAG_UNICODE_STRING); if (ObjectNameInfo == NULL) return STATUS_INSUFFICIENT_RESOURCES; /* Get the actual name info now we have the buffer to hold it */ Status = ObQueryNameString(Object, ObjectNameInfo, ReturnLength, &ReturnLength); } if (NT_SUCCESS(Status)) { /* Make sure the buffer we were passed is large enough to hold the string */ if (ObjectName->MaximumLength < ObjectNameInfo->Name.Length) { /* It wasn't, let's enlarge the buffer */ Status = FltpReallocateUnicodeString(ObjectName, ObjectNameInfo->Name.Length, FALSE); } if (NT_SUCCESS(Status)) { /* Copy the object name into the callers buffer */ RtlCopyUnicodeString(ObjectName, &ObjectNameInfo->Name); } } if (ObjectNameInfo) { ExFreePoolWithTag(ObjectNameInfo, FM_TAG_UNICODE_STRING); } return Status; }
HDC APIENTRY NtGdiOpenDCW( PUNICODE_STRING pustrDevice, DEVMODEW *pdmInit, PUNICODE_STRING pustrLogAddr, ULONG iType, BOOL bDisplay, HANDLE hspool, VOID *pDriverInfo2, VOID *pUMdhpdev) { UNICODE_STRING ustrDevice; WCHAR awcDevice[CCHDEVICENAME]; DEVMODEW dmInit; PVOID dhpdev; HDC hdc; /* Only if a devicename is given, we need any data */ if (pustrDevice) { /* Initialize destination string */ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice)); _SEH2_TRY { /* Probe the UNICODE_STRING and the buffer */ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1); ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1); /* Copy the string */ RtlCopyUnicodeString(&ustrDevice, pustrDevice); if (pdmInit) { /* FIXME: could be larger */ ProbeForRead(pdmInit, sizeof(DEVMODEW), 1); RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW)); } if (pUMdhpdev) { ProbeForWrite(pUMdhpdev, sizeof(HANDLE), 1); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); _SEH2_YIELD(return NULL); } _SEH2_END } else {
PUNICODE_STRING CopyUS(PUNICODE_STRING a) { PUNICODE_STRING b = (PUNICODE_STRING)ExAllocatePool(PagedPool,sizeof(UNICODE_STRING)); ok(b != NULL, "US is NULL after allocated memory\n"); b->Length = 0; b->MaximumLength =a->MaximumLength; b->Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, b->MaximumLength, 1633); ok(b->Buffer != NULL, "US->Buffer is NULL after allocated memory\n"); RtlCopyUnicodeString(b, a); return b; }
NTSTATUS CtxUpdateNameInStreamHandleContext ( __in PUNICODE_STRING DirectoryName, __inout PCTX_STREAMHANDLE_CONTEXT StreamHandleContext ) /*++ Routine Description: This routine updates the name of the target in the supplied stream handle context Arguments: DirectoryName - Supplies the directory name StreamHandleContext - Returns the updated name in the stream context Return Value: Status Note: The caller must synchronize access to the context. This routine does no synchronization --*/ { NTSTATUS status; PAGED_CODE(); // // Free any existing name // if (StreamHandleContext->FileName.Buffer != NULL) { CtxFreeUnicodeString(&StreamHandleContext->FileName); } // // Allocate and copy off the directory name // StreamHandleContext->FileName.MaximumLength = DirectoryName->Length; status = CtxAllocateUnicodeString(&StreamHandleContext->FileName); if (NT_SUCCESS(status)) { RtlCopyUnicodeString(&StreamHandleContext->FileName, DirectoryName); } return status; }
NTSTATUS Ctx_UpdateNameInStreamContext ( __in PUNICODE_STRING DirectoryName, __inout PSTREAM_CONTEXT StreamContext ) /*++ Routine Description: This routine updates the name of the target in the supplied stream context Arguments: DirectoryName - Supplies the directory name StreamContext - Returns the updated name in the stream context Return Value: Status Note: The caller must synchronize access to the context. This routine does no synchronization --*/ { NTSTATUS status = STATUS_SUCCESS ; PAGED_CODE(); //Free any existing name if (StreamContext->FileName.Buffer != NULL) { ExFreePoolWithTag( StreamContext->FileName.Buffer,STRING_TAG ); StreamContext->FileName.Length = StreamContext->FileName.MaximumLength = 0; StreamContext->FileName.Buffer = NULL; } //Allocate and copy off the directory name StreamContext->FileName.MaximumLength = DirectoryName->Length; StreamContext->FileName.Buffer = ExAllocatePoolWithTag( PagedPool, StreamContext->FileName.MaximumLength, STRING_TAG ); if (StreamContext->FileName.Buffer == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(&StreamContext->FileName, DirectoryName); return status; }
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS ntStatus; ntStatus= STATUS_SUCCESS; PPJoyBus_DebugLevel= PPJOY_DEFAULT_DEBUGLEVEL; PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_WARN, ("Built " __DATE__ " at " __TIME__) ); PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_FENTRY, ("DriverEntry (DriverObject=0x%p,RegistryPath=0x%p)",DriverObject, RegistryPath) ); RtlZeroMemory (&Globals,sizeof(Globals)); /* Setup copy of DriverObject first so we can use it for event log function */ Globals.DriverObject= DriverObject; /* Allocate buffer to store registry path to the parameters registry key */ Globals.ParamRegistryPath.MaximumLength= RegistryPath->Length+sizeof(UNICODE_NULL)+sizeof(PARAM_KEY_NAME); Globals.ParamRegistryPath.Length= RegistryPath->Length; Globals.ParamRegistryPath.Buffer= ExAllocatePoolWithTag (PagedPool,Globals.ParamRegistryPath.MaximumLength,PPJOYBUS_POOL_TAG); if (!Globals.ParamRegistryPath.Buffer) { PPJoyBus_WriteEventLog (PPJ_MSG_ERRORALLOCMEM,&ntStatus,sizeof(ntStatus),L""); ntStatus= STATUS_INSUFFICIENT_RESOURCES; goto Exit; } /* Copy driver registry path and append the parameters subkey name */ RtlCopyUnicodeString (&Globals.ParamRegistryPath,RegistryPath); RtlAppendUnicodeToString (&Globals.ParamRegistryPath,PARAM_KEY_NAME); ExInitializeFastMutex (&Globals.Mutex); PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_BABBLE2, ("ParamRegistryPath=%S",Globals.ParamRegistryPath.Buffer) ); /* Set up pointers to our other entry points in the DeviceObject */ DriverObject->MajorFunction[IRP_MJ_CREATE]= PPJoyBus_CreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE]= PPJoyBus_CreateClose; DriverObject->MajorFunction[IRP_MJ_POWER]= PPJoyBus_Power; DriverObject->MajorFunction[IRP_MJ_PNP]= PPJoyBus_PnP; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= PPJoyBus_Ioctl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]= PPJoyBus_InternalIoctl; DriverObject->DriverUnload= PPJoyBus_Unload; DriverObject->DriverExtension->AddDevice= PPJoyBus_AddDevice; PPJoyBus_WriteEventLog (PPJ_MSG_DRIVERSTARTEDVER,&ntStatus,sizeof(ntStatus),LVER_PRODUCTVERSION_STR); Exit: PPJOY_EXITPROC (FILE_PPJOYBUS|PPJOY_FEXIT_STATUSOK , "DriverEntry", ntStatus); return ntStatus; } /* DriverEntry */
/****************************************************************************\ * * NT_DupUnicodeString() * * DESCRIPTION: * * Allocates a copy of UNICODE string * * ARGUMENTS: * * String - string to duplicate * MaxLen - max length of the new string, in characters. If zero, allocates just enough to copy the contents of the source * * RETURN VALUE: * * Pointer to the new string, NULL if memory allocation failed * \****************************************************************************/ PUNICODE_STRING NT_DupUnicodeString(IN PUNICODE_STRING String, IN USHORT MaxLen) { PUNICODE_STRING NewString = NULL; ASSERT(String); if (String) { USHORT ActualMaxLength = MAX(MaxLen, String->Length/sizeof(WCHAR)); NewString = NT_AllocUnicodeString(ActualMaxLength); if (NewString) { RtlCopyUnicodeString( NewString, String); } } return (NewString); }
static BOOL LDEVOBJ_bLoadImage( _Inout_ PLDEVOBJ pldev, _In_ PUNICODE_STRING pustrPathName) { PSYSTEM_GDI_DRIVER_INFORMATION pDriverInfo; NTSTATUS Status; ULONG cbSize; /* Make sure no image is loaded yet */ ASSERT(pldev && pldev->pGdiDriverInfo == NULL); /* Allocate a SYSTEM_GDI_DRIVER_INFORMATION structure */ cbSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION) + pustrPathName->Length; pDriverInfo = ExAllocatePoolWithTag(PagedPool, cbSize, GDITAG_LDEV); if (!pDriverInfo) { ERR("Failed to allocate SYSTEM_GDI_DRIVER_INFORMATION\n"); return FALSE; } /* Initialize the UNICODE_STRING and copy the driver name */ RtlInitEmptyUnicodeString(&pDriverInfo->DriverName, (PWSTR)(pDriverInfo + 1), pustrPathName->Length); RtlCopyUnicodeString(&pDriverInfo->DriverName, pustrPathName); /* Try to load the driver */ Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, pDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION)); if (!NT_SUCCESS(Status)) { ERR("Failed to load a GDI driver: '%wZ', Status = 0x%lx\n", pustrPathName, Status); /* Free the allocated memory */ ExFreePoolWithTag(pDriverInfo, GDITAG_LDEV); return FALSE; } /* Set the driver info */ pldev->pGdiDriverInfo = pDriverInfo; /* Return success. */ return TRUE; }
/* * @implemented */ NTSTATUS CreateNewVolumeName(OUT PUNICODE_STRING VolumeName, IN PGUID VolumeGuid OPTIONAL) { GUID Guid; NTSTATUS Status; UNICODE_STRING GuidString; /* If no GUID was provided, then create one */ if (!VolumeGuid) { Status = ExUuidCreate(&Guid); if (!NT_SUCCESS(Status)) { return Status; } } else { RtlCopyMemory(&Guid, VolumeGuid, sizeof(GUID)); } /* Convert GUID to string */ Status = RtlStringFromGUID(&Guid, &GuidString); if (!NT_SUCCESS(Status)) { return Status; } /* Size for volume namespace, litteral GUID, and null char */ VolumeName->MaximumLength = 0x14 + 0x4C + sizeof(UNICODE_NULL); VolumeName->Buffer = AllocatePool(0x14 + 0x4C + sizeof(UNICODE_NULL)); if (!VolumeName->Buffer) { Status = STATUS_INSUFFICIENT_RESOURCES; } else { RtlCopyUnicodeString(VolumeName, &Volume); RtlAppendUnicodeStringToString(VolumeName, &GuidString); VolumeName->Buffer[VolumeName->Length / sizeof(WCHAR)] = UNICODE_NULL; Status = STATUS_SUCCESS; } ExFreePoolWithTag(GuidString.Buffer, 0); return Status; }
/*++ Routine Description: 创建一个新的上下文 This routine creates a new file context Arguments: FileName - Supplies the file name FileContext - Returns the file context Return Value: Status --*/ NTSTATUS CtxCreateFileContext ( __in PUNICODE_STRING FileName, __deref_out PCTX_FILE_CONTEXT *FileContext ) { NTSTATUS status; PCTX_FILE_CONTEXT fileContext; PAGED_CODE(); // 分配一个文件上下文 // Allocate a file context // DebugTrace(DEBUG_TRACE_FILE_CONTEXT_OPERATIONS, ("[Ctx]: Allocating file context \n")); status = FltAllocateContext( Globals.Filter, FLT_FILE_CONTEXT, CTX_FILE_CONTEXT_SIZE, PagedPool, &fileContext ); if (!NT_SUCCESS( status )) { DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR, ("[Ctx]: Failed to allocate file context with status 0x%x \n", status) ); return status; } // 初始化新创建的上下文 // Initialize the newly created context // 分配内存,并拷贝文件名 // Allocate and copy off the file name fileContext->FileName.MaximumLength = FileName->Length; status = CtxAllocateUnicodeString( &fileContext->FileName ); if (NT_SUCCESS( status )) { RtlCopyUnicodeString( &fileContext->FileName, FileName ); } *FileContext = fileContext; return STATUS_SUCCESS; }
NTSTATUS SoundCreateDeviceName( PCWSTR PrePrefix, PCWSTR Prefix, UCHAR Index, PUNICODE_STRING DeviceName ) { UNICODE_STRING Number; WCHAR NumberBuffer[5]; UNICODE_STRING uPrePrefix; UNICODE_STRING uPrefix; ULONG Size; RtlInitUnicodeString(&uPrePrefix, PrePrefix); RtlInitUnicodeString(&uPrefix, Prefix); Size = uPrePrefix.Length + uPrefix.Length + sizeof(NumberBuffer) + sizeof(UNICODE_NULL); DeviceName->Buffer = ExAllocatePool(PagedPool, Size); DeviceName->MaximumLength = (USHORT)Size; if (DeviceName->Buffer == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(DeviceName, &uPrePrefix); RtlAppendUnicodeStringToString(DeviceName, &uPrefix); if (Index != 255) { Number.Buffer = NumberBuffer; Number.MaximumLength = sizeof(NumberBuffer); RtlIntegerToUnicodeString((ULONG)Index, 10, &Number); RtlAppendUnicodeStringToString(DeviceName, &Number); } /* ** Null terminate for some uses (but don't increase the 'length' or ** the UNICODE_STRING version will have a 0 on the end. */ DeviceName->Buffer[DeviceName->Length / sizeof(UNICODE_NULL)] = UNICODE_NULL; return STATUS_SUCCESS; }
static PALIAS_HEADER IntCreateAliasHeader(PCONSRV_CONSOLE Console, PVOID ExeName, USHORT ExeLength, BOOLEAN UnicodeExe) { UNICODE_STRING ExeNameU; PALIAS_HEADER Entry; 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; Entry = ConsoleAllocHeap(0, sizeof(ALIAS_HEADER) + ExeNameU.Length); if (!Entry) { if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer); return Entry; } Entry->ExeName.Buffer = (PWSTR)(Entry + 1); Entry->ExeName.Length = 0; Entry->ExeName.MaximumLength = ExeNameU.Length; RtlCopyUnicodeString(&Entry->ExeName, &ExeNameU); Entry->Data = NULL; Entry->Next = NULL; if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer); return Entry; }
//-------------------------------------------------------------------------------------- NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"()\n"); DriverObject->DriverUnload = DriverUnload; m_Self = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection; KeInitializeMutex(&m_GlobalMutex, NULL); // save registry path if (AllocUnicodeString(&m_RegistryPath, RegistryPath->Length)) { RtlCopyUnicodeString(&m_RegistryPath, RegistryPath); DbgMsg(__FILE__, __LINE__, "Service registry path is '%wZ'\n", &m_RegistryPath); } else { return STATUS_UNSUCCESSFUL; } NTSTATUS ns = PsSetLoadImageNotifyRoutine(LoadImageNotify); if (!NT_SUCCESS(ns)) { DbgMsg(__FILE__, __LINE__, "PsSetLoadImageNotifyRoutine() fails; status: 0x%.8x\n", ns); return STATUS_UNSUCCESSFUL; } PIMAGE_NT_HEADERS32 pHeaders = (PIMAGE_NT_HEADERS32)((PUCHAR)m_Self->DllBase + ((PIMAGE_DOS_HEADER)m_Self->DllBase)->e_lfanew); PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER) (pHeaders->FileHeader.SizeOfOptionalHeader + (PUCHAR)&pHeaders->OptionalHeader); // copy sections for (ULONG i = 0; i < pHeaders->FileHeader.NumberOfSections; i++) { // erase discardable flag from our driver sections pSection->Characteristics &= ~IMAGE_SCN_MEM_DISCARDABLE; pSection += 1; } m_RequiredSize = pHeaders->OptionalHeader.SizeOfImage; return STATUS_SUCCESS; }
VOID WINAPI InitCommandLines(VOID) { PRTL_USER_PROCESS_PARAMETERS Params; /* get command line */ Params = NtCurrentPeb()->ProcessParameters; RtlNormalizeProcessParams (Params); /* initialize command line buffers */ CommandLineStringW.Length = Params->CommandLine.Length; CommandLineStringW.MaximumLength = CommandLineStringW.Length + sizeof(WCHAR); CommandLineStringW.Buffer = RtlAllocateHeap(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, CommandLineStringW.MaximumLength); if (CommandLineStringW.Buffer == NULL) { return; } RtlInitAnsiString(&CommandLineStringA, NULL); /* Copy command line */ RtlCopyUnicodeString(&CommandLineStringW, &(Params->CommandLine)); CommandLineStringW.Buffer[CommandLineStringW.Length / sizeof(WCHAR)] = 0; /* convert unicode string to ansi (or oem) */ if (bIsFileApiAnsi) RtlUnicodeStringToAnsiString(&CommandLineStringA, &CommandLineStringW, TRUE); else RtlUnicodeStringToOemString(&CommandLineStringA, &CommandLineStringW, TRUE); CommandLineStringA.Buffer[CommandLineStringA.Length] = 0; bCommandLineInitialized = TRUE; }
//read EnableReplace key from reg to check if replace the key with our define key void ReadRegistery(IN PUNICODE_STRING RegistryPath) { UNICODE_STRING parameter_path; RTL_QUERY_REGISTRY_TABLE query_table[2]; NTSTATUS status; parameter_path.Length = 0; parameter_path.MaximumLength = RegistryPath->Length + sizeof(PARAMETER_KEY); parameter_path.Buffer = (PWSTR) ExAllocatePool(PagedPool, parameter_path.MaximumLength); if (parameter_path.Buffer == NULL) { return; } RtlZeroMemory(parameter_path.Buffer,parameter_path.MaximumLength); RtlCopyUnicodeString(¶meter_path, RegistryPath); RtlAppendUnicodeToString(¶meter_path, PARAMETER_KEY); RtlZeroMemory(&query_table[0], sizeof(query_table)); query_table[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; query_table[0].Name = ENABLEWRITEPORT_VALUE; query_table[0].EntryContext = &bEnableReplace; status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, parameter_path.Buffer, &query_table[0], NULL, NULL ); ExFreePool(parameter_path.Buffer); if (!NT_SUCCESS(status)) { KdPrint(("Kb_sniff_Mp: Query registry failed.\n")); } }
void NTAPI WallALERecvAcceptClassify( IN const FWPS_INCOMING_VALUES* inFixedValues, IN const FWPS_INCOMING_METADATA_VALUES* inMetaValues, IN OUT void* layerData, IN const void* classifyContext, IN const FWPS_FILTER* filter, IN UINT64 flowContext, OUT FWPS_CLASSIFY_OUT* classifyOut ) /*++ --*/ { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING devName,dosName; WCHAR buffer[MAX_PATH_LEN]; PMY_UNICODE_STRING logData; PWALL_PENDED_PACKET pendedRecv = NULL; BOOLEAN bWakeUp = FALSE; ADDRESS_FAMILY addressFamily; LOG("into\n"); if(!(classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)) { KdPrint(("write right not set!\n")); return; } if( layerData != NULL ) { FWPS_PACKET_INJECTION_STATE state; state = FwpsQueryPacketInjectionState( gInjectHandle, layerData, NULL); KdPrint(("inject state:%x\n",state )); if( state == FWPS_PACKET_INJECTED_BY_SELF || state == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF ) { classifyOut->actionType = FWP_ACTION_PERMIT; KdPrint(("inject by self\n")); goto exit; } } addressFamily = GetAddressFamilyForLayer(inFixedValues->layerId); if(!IsAleReauthorize(inFixedValues)) { pendedRecv = WallAllocateAndInitPendedPacket( inFixedValues, inMetaValues, addressFamily, layerData, WALL_DATA_PACKET, FWP_DIRECTION_INBOUND ); if(pendedRecv == NULL ) { classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; goto exit; } ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_COMPLETION_HANDLE)); status = FwpsPendOperation0( inMetaValues->completionHandle, &pendedRecv->completionContext ); if (!NT_SUCCESS(status)) { classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; goto exit; } bWakeUp = IsListEmpty(&gPacketList->list) && IsListEmpty(&gConnList->list); ExInterlockedInsertTailList( &gPacketList->list,&pendedRecv->list,&gPacketList->lock ); pendedRecv = NULL; if( bWakeUp ) { RunMyProcess( WallInspectWallPackets,NULL ); } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; } else {//reauth FWP_DIRECTION packetDirection; KIRQL irql,irql2; KdPrint(("recv reauth!\n")); classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; } exit: if( classifyOut->actionType == FWP_ACTION_PERMIT ) { RtlInitUnicodeString( &devName,(PWCHAR)inMetaValues->processPath->data ); RtlInitEmptyUnicodeString( &dosName,buffer,MAX_PATH_LEN * sizeof(WCHAR)); logData = MyExAllocatePool( sizeof( MY_UNICODE_STRING) + inMetaValues->processPath->size); if( logData != NULL) { logData->str.Buffer = logData->buffer; logData->str.MaximumLength = (USHORT)inMetaValues->processPath->size; status = DevicePathToDosPath( &devName,&dosName ); if( NT_SUCCESS( status )) { RtlCopyUnicodeString( (PUNICODE_STRING)logData,&dosName ); } else { RtlCopyUnicodeString( (PUNICODE_STRING)logData,&devName ); } RunMyProcess( WallWriteConnectLogData,logData ); logData = NULL; } } return; }
void NTAPI WallALEConnectClassify( IN const FWPS_INCOMING_VALUES* inFixedValues, IN const FWPS_INCOMING_METADATA_VALUES* inMetaValues, IN OUT void* layerData, IN const void* classifyContext, IN const FWPS_FILTER* filter, IN UINT64 flowContext, OUT FWPS_CLASSIFY_OUT* classifyOut ) /*++ 注意:此回调的Irql <= DISPATCH_LEVEL!!!!! --*/ { NTSTATUS status = STATUS_SUCCESS; PWALL_PENDED_PACKET pendedConn = NULL; BOOLEAN bWakeUp = FALSE; ADDRESS_FAMILY addressFamily; UNICODE_STRING devName,dosName; WCHAR buffer[MAX_PATH_LEN]; PMY_UNICODE_STRING logData = NULL; LOG("into\n"); if(!(classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)) { KdPrint(("write right not set!\n")); return; } if( layerData != NULL ) { FWPS_PACKET_INJECTION_STATE state; state = FwpsQueryPacketInjectionState( gInjectHandle, layerData, NULL); if( state == FWPS_PACKET_INJECTED_BY_SELF || state == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF ) { classifyOut->actionType = FWP_ACTION_PERMIT; goto exit; } } addressFamily = GetAddressFamilyForLayer(inFixedValues->layerId); if(!IsAleReauthorize(inFixedValues)) { pendedConn = WallAllocateAndInitPendedPacket( inFixedValues, inMetaValues, addressFamily, layerData, WALL_CONNECT_PACKET, FWP_DIRECTION_OUTBOUND ); if(pendedConn == NULL ) { classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; goto exit; } ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_COMPLETION_HANDLE)); status = FwpsPendOperation0( inMetaValues->completionHandle, &pendedConn->completionContext ); if (!NT_SUCCESS(status)) { classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; goto exit; } bWakeUp = IsListEmpty(&gPacketList->list) && IsListEmpty(&gConnList->list); ExInterlockedInsertTailList( &gConnList->list,&pendedConn->list,&gConnList->lock ); pendedConn = NULL; if( bWakeUp ) { RunMyProcess( WallInspectWallPackets,NULL ); } classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; } else {//reauth FWP_DIRECTION packetDirection; KIRQL irql,irql2; LOG("1\n"); ASSERT(FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_PACKET_DIRECTION)); packetDirection = inMetaValues->packetDirection; if (packetDirection == FWP_DIRECTION_OUTBOUND) { LIST_ENTRY* listEntry; BOOLEAN authComplete = FALSE; LOG("2\n"); KeAcquireSpinLock( &gConnList->lock,&irql ); LOG("22\n"); for (listEntry = gConnList->list.Flink; listEntry != (PLIST_ENTRY)gConnList; ) { pendedConn = (PWALL_PENDED_PACKET)listEntry; listEntry = listEntry->Flink; if (IsMatchingConnectPacket( inFixedValues, addressFamily, packetDirection, pendedConn ) && (pendedConn->authConnectDecision != 0)) { ASSERT((pendedConn->authConnectDecision == FWP_ACTION_PERMIT) || (pendedConn->authConnectDecision == FWP_ACTION_BLOCK)); LOG("3\n"); classifyOut->actionType = pendedConn->authConnectDecision; if( classifyOut->actionType == FWP_ACTION_BLOCK ){ classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; } RemoveEntryList(&pendedConn->list); if (/*!gDriverUnloading &&*/ (pendedConn->netBufferList != NULL) && (pendedConn->authConnectDecision == FWP_ACTION_PERMIT)) { pendedConn->type = WALL_DATA_PACKET; LOG("4\n"); KeAcquireSpinLock( &gPacketList->lock,&irql2 ); bWakeUp = IsListEmpty(&gPacketList->list) && IsListEmpty(&gConnList->list); InsertTailList(&gPacketList->list, &pendedConn->list); pendedConn = NULL; // ownership transferred KeReleaseSpinLock( &gPacketList->lock,irql2 ); if (bWakeUp) { RunMyProcess( WallInspectWallPackets,NULL ); } }//end if permit authComplete = TRUE; break; }//end if match }//end if for KeReleaseSpinLock( &gConnList->lock,irql ); if (authComplete) { LOG("5\n"); goto exit; } else { pendedConn = NULL; } }//end if outbound classifyOut->actionType = FWP_ACTION_BLOCK; classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE; classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB; } exit: if( pendedConn != NULL ) { LOG("free packet\n"); WallFreePendedPacket( pendedConn ); pendedConn = NULL; } if( classifyOut->actionType == FWP_ACTION_PERMIT ) { RtlInitUnicodeString( &devName,(PWCHAR)inMetaValues->processPath->data ); RtlInitEmptyUnicodeString( &dosName,buffer,MAX_PATH_LEN * sizeof(WCHAR)); logData = MyExAllocatePool( sizeof( MY_UNICODE_STRING) + inMetaValues->processPath->size); if( logData != NULL) { logData->str.Buffer = logData->buffer; logData->str.MaximumLength = (USHORT)inMetaValues->processPath->size; status = DevicePathToDosPath( &devName,&dosName ); if( NT_SUCCESS( status )) { RtlCopyUnicodeString( (PUNICODE_STRING)logData,&dosName ); } else { RtlCopyUnicodeString( (PUNICODE_STRING)logData,&devName ); } KdPrint(("logData:%wZ\n",logData )); RunMyProcess( WallWriteConnectLogData,logData ); logData = NULL; } } return; }
/* Calls ClientLoadLibrary in user32 */ BOOL NTAPI co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName, PUNICODE_STRING pstrInitFunc, BOOL Unload, BOOL ApiHook) { PVOID ResultPointer; ULONG ResultLength; ULONG ArgumentLength; PCLIENT_LOAD_LIBRARY_ARGUMENTS pArguments; NTSTATUS Status; BOOL bResult; ULONG_PTR pLibNameBuffer = 0, pInitFuncBuffer = 0; /* Do not allow the desktop thread to do callback to user mode */ ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread); TRACE("co_IntClientLoadLibrary: %S, %S, %d, %d\n", pstrLibName->Buffer, pstrLibName->Buffer, Unload, ApiHook); /* Calculate the size of the argument */ ArgumentLength = sizeof(CLIENT_LOAD_LIBRARY_ARGUMENTS); if(pstrLibName) { pLibNameBuffer = ArgumentLength; ArgumentLength += pstrLibName->Length + sizeof(WCHAR); } if(pstrInitFunc) { pInitFuncBuffer = ArgumentLength; ArgumentLength += pstrInitFunc->Length + sizeof(WCHAR); } /* Allocate the argument */ pArguments = IntCbAllocateMemory(ArgumentLength); if(pArguments == NULL) { return FALSE; } /* Fill the argument */ pArguments->Unload = Unload; pArguments->ApiHook = ApiHook; if(pstrLibName) { /* Copy the string to the callback memory */ pLibNameBuffer += (ULONG_PTR)pArguments; pArguments->strLibraryName.Buffer = (PWCHAR)pLibNameBuffer; pArguments->strLibraryName.MaximumLength = pstrLibName->Length + sizeof(WCHAR); RtlCopyUnicodeString(&pArguments->strLibraryName, pstrLibName); /* Fix argument pointer to be relative to the argument */ pLibNameBuffer -= (ULONG_PTR)pArguments; pArguments->strLibraryName.Buffer = (PWCHAR)(pLibNameBuffer); } else { RtlZeroMemory(&pArguments->strLibraryName, sizeof(UNICODE_STRING)); } if(pstrInitFunc) { /* Copy the strings to the callback memory */ pInitFuncBuffer += (ULONG_PTR)pArguments; pArguments->strInitFuncName.Buffer = (PWCHAR)pInitFuncBuffer; pArguments->strInitFuncName.MaximumLength = pstrInitFunc->Length + sizeof(WCHAR); RtlCopyUnicodeString(&pArguments->strInitFuncName, pstrInitFunc); /* Fix argument pointers to be relative to the argument */ pInitFuncBuffer -= (ULONG_PTR)pArguments; pArguments->strInitFuncName.Buffer = (PWCHAR)(pInitFuncBuffer); } else { RtlZeroMemory(&pArguments->strInitFuncName, sizeof(UNICODE_STRING)); } /* Do the callback */ UserLeaveCo(); Status = KeUserModeCallback(USER32_CALLBACK_CLIENTLOADLIBRARY, pArguments, ArgumentLength, &ResultPointer, &ResultLength); UserEnterCo(); /* Free the argument */ IntCbFreeMemory(pArguments); if(!NT_SUCCESS(Status)) { return FALSE; } _SEH2_TRY { /* Probe and copy the usermode result data */ ProbeForRead(ResultPointer, sizeof(HMODULE), 1); bResult = *(BOOL*)ResultPointer; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { bResult = FALSE; } _SEH2_END; return bResult; }
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); }