HANDLE WINAPI _AvpCreateFile ( LPCTSTR lpFileName, // pointer to name of the file DWORD dwDesiredAccess, // access (read-write) DWORD dwShareMode, // share mode SECURITY_ATTRIBUTES FAR* lpSecurityAttributes, // pointer to security descriptor DWORD dwCreationDistribution, // how to create DWORD dwFlagsAndAttributes, // file attributes HANDLE hTemplateFile // handle to file with attributes to copy ) { int n=InternalAccessAdd(lpFileName); // _DebugTrace(TraceInfo,"AvpCreateFile %d: %s access:%08X\n",lpFileName,lpFileName,dwDesiredAccess); int access_=0; switch(dwCreationDistribution) { case CREATE_NEW: access_=FILE_CREATE; break; case CREATE_ALWAYS: access_=FILE_OVERWRITE_IF; break; case OPEN_EXISTING: access_=FILE_OPEN; break; case OPEN_ALWAYS: access_=FILE_OPEN_IF; break; case TRUNCATE_EXISTING: access_=FILE_OVERWRITE; break; default: access_=FILE_OPEN; break; } // if(dwShareMode & FILE_SHARE_WRITE) dwShareMode|=FILE_SHARE_DELETE; dwShareMode |= FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE; HANDLE r=(HANDLE)OpenFile((LPTSTR)lpFileName,dwDesiredAccess,dwShareMode,access_); if(r!=INVALID_HANDLE_VALUE) { if(LimitCompoundSize){ if( dwDesiredAccess==GENERIC_READ && (_AvpGetFileSize(r,NULL) >= LimitCompoundSize)){ if(so_ptr) so_ptr->MFlags&=~(MF_ARCHIVED|MF_PACKED|MF_MAILBASES|MF_MAILPLAIN); _DebugTrace(TraceInfo,"Change MFlags by limitcompoundsize"); } } if(NumberHandles>24) { ++InMyOpenClose; ZwClose( r ); --InMyOpenClose; r=INVALID_HANDLE_VALUE; } else NumberHandles++; } _DebugTrace(TraceInfo,"AvpCreateFile %d :%s\n",r,lpFileName); if(r==INVALID_HANDLE_VALUE) InternalAccessRemoveAt(n); else InternalAccessHandleSetAt(n, (DWORD)r); return r; }
NTSTATUS Serenum_IoCtl ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: --*/ { PIO_STACK_LOCATION irpStack; NTSTATUS status; PCOMMON_DEVICE_DATA commonData; PFDO_DEVICE_DATA fdoData; HANDLE keyHandle; ULONG actualLength; status = STATUS_SUCCESS; irpStack = IoGetCurrentIrpStackLocation (Irp); ASSERT (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction); commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension; fdoData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension; status = IoAcquireRemoveLock(&commonData->RemoveLock, Irp); if (!NT_SUCCESS(status)){ Irp->IoStatus.Information = 0; Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } //buffer = Irp->AssociatedIrp.SystemBuffer; // // We only take Device Control requests for the FDO. // That is the bus itself. // // The request is one of the propriatary Ioctls for // // NB We ARE a filter driver, so we DO pass on the irp if we don't handle it // //inlen = irpStack->Parameters.DeviceIoControl.InputBufferLength; //outlen = irpStack->Parameters.DeviceIoControl.OutputBufferLength; if (!commonData->IsFDO) { // // These commands are only allowed to go to the FDO. Since they came // into the PDO, we need to fire them down to the serenum Fdo. // return Serenum_Generic_FireAndRelease_RemoveLock(((PPDO_DEVICE_DATA) DeviceObject->DeviceExtension)->ParentFdo,Irp); } switch (irpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_SERENUM_GET_PORT_NAME: // // Get the port name from the registry. // This IOCTL is used by the modem cpl. // status = IoOpenDeviceRegistryKey(fdoData->UnderlyingPDO, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_READ, &keyHandle); if (!NT_SUCCESS(status)) { // // This is a fatal error. If we can't get to our registry key, // we are sunk. // Serenum_KdPrint_Def (SER_DBG_PNP_ERROR, ("IoOpenDeviceRegistryKey failed - %x \n", status)); Irp->IoStatus.Information = 0; } else { status = Serenum_GetRegistryKeyValue( keyHandle, L"PortName", sizeof(L"PortName"), Irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.OutputBufferLength, &actualLength); if ( STATUS_OBJECT_NAME_NOT_FOUND == status || STATUS_INVALID_PARAMETER == status ) { status = Serenum_GetRegistryKeyValue( keyHandle, L"Identifier", sizeof(L"Identifier"), Irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.DeviceIoControl.OutputBufferLength, &actualLength); } Irp->IoStatus.Information = actualLength; ZwClose (keyHandle); } break; default: // // This is not intended for us - fire and Protect! // return Serenum_DispatchPassThroughWithoutAcquire( DeviceObject, Irp); } IoReleaseRemoveLock(&commonData->RemoveLock, Irp); Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; }
/** * 写日志函数 * @param iLevel:ULONG,要写入日志信息的等级,请参考LogConst.h文件内等级。 * @param format:NTSTRSAFE_PSTR*,输入信息的格式,此格式参考printf。 * @param ...:变参,参考printf,要写入的信息。 * 写日志信息接口,写日志信息大小请不要超过规定长度的大小!最大暂时为256字节!! */ void _cdecl WriteSysLog(ULONG iLevel, NTSTRSAFE_PWSTR format,...) { //判断记录日志级别 if(iLevel > g_logLevel) return; //获得互斥体,在下面的调用中,所有的函数退出部分都要进行释放互斥体 KeWaitForSingleObject(&g_logMutex, Executive, KernelMode, FALSE, NULL); HANDLE logfile; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK ioStatus; NTSTATUS ntStatus; InitializeObjectAttributes(&objectAttributes,&g_logFileName,OBJ_CASE_INSENSITIVE,NULL, NULL); ntStatus = ZwCreateFile(&logfile,FILE_READ_ATTRIBUTES | FILE_APPEND_DATA | SYNCHRONIZE, &objectAttributes,&ioStatus,NULL,FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0); if(!NT_SUCCESS(ntStatus) ) { KeReleaseMutex(&g_logMutex,FALSE); KdPrint( ("Strategy:%d:Init Open file error!\n",g_logStrategy) ); return; } //判断文件大小处理的函数 if(g_logWriteTime >= CHECK_TIME) { if(g_logStrategy == 1) { ntStatus = CheckLogFileSizeAndReCreateLogFile(&g_logFileName,1,logfile); if(!NT_SUCCESS(ntStatus) ) { KeReleaseMutex(&g_logMutex,FALSE); KdPrint( ("Strategy:%d:Init Open file error!\n",g_logStrategy) ); return; } } g_logWriteTime = 0; } TIME_FIELDS ctime; ctime = GetLocalTime(); ULONG pid = (ULONG)PsGetCurrentProcessId(); PWCHAR ptype; switch(iLevel) { case LOG_TYPE_ERROR: ptype = L"ERROR";break; case LOG_TYPE_WARN: ptype = L"WARNING";break; case LOG_TYPE_INFO: ptype = L"INFO";break; default: ptype = L"DEBUG";break; } WCHAR strTemp[MAX_INFO_LENGTH]; RtlZeroMemory(strTemp, MAX_INFO_LENGTH); NTSTRSAFE_PWSTR pinfo = strTemp; va_list args; va_start(args,format); ntStatus =::RtlStringCchVPrintfW(pinfo,MAX_INFO_LENGTH*sizeof(WCHAR),format,args); if( !NT_SUCCESS(ntStatus) ) { DbgPrint( ("Log info conversion error1!\n") ); ZwClose(logfile); KeReleaseMutex(&g_logMutex,FALSE); //在函数所有的出口释放互斥体 return; } va_end(args); WCHAR cinfo[MAX_INFO_LENGTH*2]; RtlZeroMemory(cinfo,MAX_INFO_LENGTH*2*sizeof(WCHAR));//清0,为了下面的操作顺利 ntStatus = RtlStringCchPrintfW(cinfo,MAX_INFO_LENGTH*2*sizeof(WCHAR), L"%04d-%02d-%02d %02d:%02d:%02d.%03d\t%d\t%s\t%s\r\n", ctime.Year, ctime.Month, ctime.Day, ctime.Hour, ctime.Minute, ctime.Second, ctime.Milliseconds,pid,ptype,pinfo); if( !NT_SUCCESS(ntStatus) ) { DbgPrint( ("Log info conversion error2!\n") ); //在函数所有的出口释放互斥体 ZwClose(logfile); KeReleaseMutex(&g_logMutex,FALSE); return; } size_t length; ntStatus = RtlStringCchLengthW(cinfo,MAX_INFO_LENGTH*2,&length); if( !NT_SUCCESS(ntStatus) ) { DbgPrint( ("Log info conversion error3!\n") ); //在函数所有的出口释放互斥体 ZwClose(logfile); KeReleaseMutex(&g_logMutex,FALSE); return; } ntStatus = ZwWriteFile(logfile,NULL,NULL,NULL,&ioStatus,cinfo,length*sizeof(WCHAR),NULL,NULL); if( !NT_SUCCESS(ntStatus) ) { DbgPrint( ("Write log error!\n") ); ZwClose(logfile); //在函数所有的出口释放互斥体 KeReleaseMutex(&g_logMutex,FALSE); return; } g_logWriteTime ++;//增加写入次数 ZwClose(logfile); KeReleaseMutex(&g_logMutex,FALSE); //KdPrint( ("write log successful!\n") ); }
VOID REINITIALIZE_ADAPTER( PVOID ) /*++ Routine Description This routine re-initializes display driver to obtains its DrvCoptBits pointer. This routine executed as a separate thread in the context of CSRSS.EXE Arguments PVOID Thread context, always NULL Return Value None, thread terminates by call PsTerminateSystemThread Environment Separate thread of CSRSS process --*/ { // // This routine runs in the context of csrss.exe // KdPrint(("REINITIALIZE_ADAPTER enter\n")); HANDLE hDrv = EngLoadImage (L"vid_copy.dll"); KdPrint(("vid_copy is %X\n", hDrv)); if (hDrv) { BOOLEAN (NTAPI *pOriginalDrvEnableDriver)( ULONG iEngineVersion, ULONG cj, PDRVENABLEDATA pded ); *(PVOID*)&pOriginalDrvEnableDriver = EngFindImageProcAddress (hDrv, "DrvEnableDriver"); KdPrint(("pOriginalDrvEnableDriver = %X\n", pOriginalDrvEnableDriver)); if (pOriginalDrvEnableDriver) { BOOLEAN Ret; DRVENABLEDATA DrvEnableData = {0}; Ret = pOriginalDrvEnableDriver (DDI_DRIVER_VERSION_NT5_01_SP1, sizeof(DrvEnableData), &DrvEnableData); KdPrint(("pOriginalDrvEnableDriver returned %X\n", Ret)); if (Ret) { for (ULONG i = 0; i<DrvEnableData.c; i++) { if (DrvEnableData.pdrvfn[i].iFunc == INDEX_DrvCopyBits) { KdPrint(("Found DrvCopyBits: %X\n", DrvEnableData.pdrvfn[i].pfn)); HANDLE hKey; wchar_t value[512]; hKey = RegOpenKey (L"\\Registry\\Machine\\Software\\NGdbg", KEY_QUERY_VALUE); if (hKey) { ULONG Len = sizeof(value); if (RegQueryValue (hKey, L"DisplayDriver", REG_SZ, value, &Len)) { KdPrint(("Display driver: %S\n", value)); wcscat (value, L".dll"); PVOID OrigBase = FindImage (value); PVOID VidBase = FindImage (L"vid_copy.dll"); if (OrigBase && VidBase) { ULONG Offset = (ULONG)DrvEnableData.pdrvfn[i].pfn - (ULONG)VidBase; KdPrint(("Offset %X\n", Offset)); pDrvCopyBits = (PUCHAR)OrigBase + Offset; KdPrint(("DrvCopyBits %X\n", pDrvCopyBits)); } else { KdPrint(("FindImage failed: OrigBase %X, VidBase %X\n", OrigBase, VidBase)); } } else { KdPrint(("RegQueryValue failed\n")); } ZwClose (hKey); } else { KdPrint(("RegOpenKey failed\n")); } } } } } EngUnloadImage (hDrv); } KdPrint(("REINITIALIZE_ADAPTER exit\n")); PsTerminateSystemThread (0); }
NTSTATUS LpxTdiOpenControl ( OUT PHANDLE ControlFileHandle, OUT PFILE_OBJECT *ControlFileObject, IN PVOID ControlContext ) { HANDLE controlFileHandle; PFILE_OBJECT controlFileObject; UNICODE_STRING nameString; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; UNREFERENCED_PARAMETER(ControlContext); LtDebugPrint (3, ("LpxTdiOpenControl: Entered\n")); // // Init object attributes // RtlInitUnicodeString (&nameString, TRANSPORT_NAME); InitializeObjectAttributes ( &objectAttributes, &nameString, 0, NULL, NULL ); status = ZwCreateFile( &controlFileHandle, GENERIC_READ, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, 0, 0, NULL, // Open as control 0 // ); if (!NT_SUCCESS(status)) { LtDebugPrint (0, ("[LpxTdi] TdiOpenControl: FAILURE, ZwCreateFile returned status code=%x\n", status)); *ControlFileHandle = NULL; *ControlFileObject = NULL; return status; } status = ioStatusBlock.Status; if (!NT_SUCCESS(status)) { LtDebugPrint (0, ("[LpxTdi] TdiOpenControl: FAILURE, IoStatusBlock.Status contains status code=%x\n", status)); *ControlFileHandle = NULL; *ControlFileObject = NULL; return status; } status = ObReferenceObjectByHandle ( controlFileHandle, 0L, NULL, KernelMode, (PVOID *) &controlFileObject, NULL ); if (!NT_SUCCESS(status)) { LtDebugPrint(0, ("[LpxTdi] LpxOpenControl: ObReferenceObjectByHandle() failed. STATUS=%08lx\n", status)); ZwClose(controlFileHandle); *ControlFileHandle = NULL; *ControlFileObject = NULL; return status; } *ControlFileHandle = controlFileHandle; *ControlFileObject = controlFileObject; LtDebugPrint (3, ("[LpxTdi] LpxOpenControl: returning\n")); return status; }
NTSTATUS NTAPI ClassSetDeviceParameter( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PWSTR SubkeyName OPTIONAL, IN PWSTR ParameterName, IN ULONG ParameterValue) { NTSTATUS status; HANDLE deviceParameterHandle; HANDLE deviceSubkeyHandle; PAGED_CODE(); // // open the given parameter // status = IoOpenDeviceRegistryKey(FdoExtension->LowerPdo, PLUGPLAY_REGKEY_DEVICE, KEY_READ | KEY_WRITE, &deviceParameterHandle); if (NT_SUCCESS(status) && (SubkeyName != NULL)) { UNICODE_STRING subkeyName; OBJECT_ATTRIBUTES objectAttributes; RtlInitUnicodeString(&subkeyName, SubkeyName); InitializeObjectAttributes(&objectAttributes, &subkeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, deviceParameterHandle, NULL); status = ZwCreateKey(&deviceSubkeyHandle, KEY_READ | KEY_WRITE, &objectAttributes, 0, NULL, 0, NULL); if (!NT_SUCCESS(status)) { ZwClose(deviceParameterHandle); } } if (NT_SUCCESS(status)) { status = RtlWriteRegistryValue( RTL_REGISTRY_HANDLE, (PWSTR) (SubkeyName ? deviceSubkeyHandle : deviceParameterHandle), ParameterName, REG_DWORD, &ParameterValue, sizeof(ULONG)); // // close what we open // if (SubkeyName) { ZwClose(deviceSubkeyHandle); } ZwClose(deviceParameterHandle); } return status; } // end ClassSetDeviceParameter()
/* Attempt to impersonate a client and open a file for the filedisk. */ static VOID STDCALL WvFilediskOpenInThread_(IN OUT WVL_SP_THREAD_ITEM item) { WV_SP_FILEDISK_OPENER_ opener = CONTAINING_RECORD( item, WV_S_FILEDISK_OPENER_, item[0] ); OBJECT_ATTRIBUTES obj_attrs; HANDLE file = NULL; IO_STATUS_BLOCK io_status; FILE_STANDARD_INFORMATION file_info; /* Impersonate the user creating the filedisk. */ opener->status = WvFilediskImpersonate(opener->filedisk->impersonation); if (!NT_SUCCESS(opener->status)) { DBG("Couldn't impersonate!\n"); goto err_impersonate; } /* Open the file. */ InitializeObjectAttributes( &obj_attrs, opener->file_path, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL ); /* Open the file. The handle is closed when the thread finishes. */ opener->status = ZwCreateFile( &file, GENERIC_READ | GENERIC_WRITE, &obj_attrs, &io_status, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_NO_INTERMEDIATE_BUFFERING | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if (!NT_SUCCESS(opener->status)) { DBG("Couldn't open file!\n"); goto err_open; } /* Determine the disk's size. */ opener->status = ZwQueryInformationFile( file, &io_status, &file_info, sizeof file_info, FileStandardInformation ); if (!NT_SUCCESS(opener->status)) { DBG("Couldn't query file size!\n"); goto err_query_info; } opener->filedisk->disk->LBADiskSize = file_info.EndOfFile.QuadPart / opener->filedisk->disk->SectorSize; /* * A really stupid "hash". RtlHashUnicodeString() would have been * good, but is only available >= Windows XP. */ opener->filedisk->hash = (UINT32) opener->filedisk->disk->LBADiskSize; { PWCHAR path_iterator = opener->file_path->Buffer; while (*path_iterator) opener->filedisk->hash += *path_iterator++; } /* Opened. */ opener->filedisk->file = file; goto out; err_query_info: ZwClose(file); err_open: out: WvFilediskStopImpersonating(); err_impersonate: KeSetEvent(opener->completion, 0, FALSE); return; }
NTSTATUS tdi_open_connection_endpoint(PUNICODE_STRING devName, PVOID connectionContext, BOOLEAN shared, PHANDLE connectionHandle, PFILE_OBJECT *connectionFileObject) { OBJECT_ATTRIBUTES attr; PFILE_FULL_EA_INFORMATION eaBuffer; ULONG eaSize; PVOID *context; IO_STATUS_BLOCK iosb; NTSTATUS status; #if (VER_PRODUCTBUILD >= 2195) InitializeObjectAttributes(&attr, devName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); #else InitializeObjectAttributes(&attr, devName, OBJ_CASE_INSENSITIVE, NULL, NULL); #endif eaSize = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) + TDI_CONNECTION_CONTEXT_LENGTH + 1 + sizeof(int); eaBuffer = HttpDiskPalloc(eaSize); if (eaBuffer == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } eaBuffer->NextEntryOffset = 0; eaBuffer->Flags = 0; eaBuffer->EaNameLength = TDI_CONNECTION_CONTEXT_LENGTH; eaBuffer->EaValueLength = sizeof(int); RtlCopyMemory(eaBuffer->EaName, TdiConnectionContext, eaBuffer->EaNameLength + 1); context = (PVOID*) &(eaBuffer->EaName[eaBuffer->EaNameLength + 1]); *context = connectionContext; status = ZwCreateFile( connectionHandle, GENERIC_READ | GENERIC_WRITE, &attr, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, shared ? FILE_SHARE_READ | FILE_SHARE_WRITE : 0, FILE_OPEN, 0, eaBuffer, eaSize ); ExFreePool(eaBuffer); if (!NT_SUCCESS(status)) { return status; } status = ObReferenceObjectByHandle(*connectionHandle, FILE_ALL_ACCESS, NULL, KernelMode, connectionFileObject, NULL); if (!NT_SUCCESS(status)) { ZwClose(*connectionHandle); return status; } return STATUS_SUCCESS; }
NTSTATUS tdi_open_transport_address(PUNICODE_STRING devName, ULONG addr, USHORT port, BOOLEAN shared, PHANDLE addressHandle, PFILE_OBJECT *addressFileObject) { OBJECT_ATTRIBUTES attr; PFILE_FULL_EA_INFORMATION eaBuffer; ULONG eaSize; PTA_IP_ADDRESS localAddr; IO_STATUS_BLOCK iosb; NTSTATUS status; #if (VER_PRODUCTBUILD >= 2195) InitializeObjectAttributes(&attr, devName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); #else InitializeObjectAttributes(&attr, devName, OBJ_CASE_INSENSITIVE, NULL, NULL); #endif eaSize = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) + TDI_TRANSPORT_ADDRESS_LENGTH + 1 + sizeof(TA_IP_ADDRESS); eaBuffer = HttpDiskPalloc(eaSize); if (eaBuffer == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } eaBuffer->NextEntryOffset = 0; eaBuffer->Flags = 0; eaBuffer->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH; eaBuffer->EaValueLength = sizeof(TA_IP_ADDRESS); RtlCopyMemory(eaBuffer->EaName, TdiTransportAddress, eaBuffer->EaNameLength + 1); localAddr = (PTA_IP_ADDRESS)(eaBuffer->EaName + eaBuffer->EaNameLength + 1); localAddr->TAAddressCount = 1; localAddr->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; localAddr->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; localAddr->Address[0].Address[0].sin_port = port; localAddr->Address[0].Address[0].in_addr = addr; RtlZeroMemory(localAddr->Address[0].Address[0].sin_zero, sizeof(localAddr->Address[0].Address[0].sin_zero)); status = ZwCreateFile( addressHandle, GENERIC_READ | GENERIC_WRITE, &attr, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, shared ? FILE_SHARE_READ | FILE_SHARE_WRITE : 0, FILE_OPEN, 0, eaBuffer, eaSize ); ExFreePool(eaBuffer); if (!NT_SUCCESS(status)) { return status; } status = ObReferenceObjectByHandle(*addressHandle, FILE_ALL_ACCESS, NULL, KernelMode, addressFileObject, NULL); if (!NT_SUCCESS(status)) { ZwClose(*addressHandle); return status; } return STATUS_SUCCESS; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath ) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING deviceName; HANDLE threadHandle; DDProxyLoadConfig(registryPath); // // To proxy UDP traffic, a new destination port or a pair of inspect and // proxy ip address need to be pre-configured. To proxy UDP traffic, a // pair of inspect and proxy ip addresses must be pre-configured. // if (configInspectUdp) { if ((configInspectDestPort == configNewDestPort) && (((configInspectDestAddrV4 == NULL) || (configNewDestAddrV4 == NULL)) && ((configInspectDestAddrV6 == NULL) || (configNewDestAddrV6 == NULL)))) { status = STATUS_DEVICE_CONFIGURATION_ERROR; goto Exit; } } else { if (((configInspectDestAddrV4 == NULL) || (configNewDestAddrV4 == NULL)) && ((configInspectDestAddrV6 == NULL) || (configNewDestAddrV6 == NULL))) { status = STATUS_DEVICE_CONFIGURATION_ERROR; goto Exit; } } RtlInitUnicodeString( &deviceName, L"\\Device\\StreamEitor" ); status = IoCreateDevice( driverObject, 0, &deviceName, FILE_DEVICE_NETWORK, 0, FALSE, &gDeviceObject ); if (!NT_SUCCESS(status)) { goto Exit; } status = FwpsInjectionHandleCreate0( AF_UNSPEC, FWPS_INJECTION_TYPE_TRANSPORT, &gInjectionHandle ); if (!NT_SUCCESS(status)) { goto Exit; } InitializeListHead(&gFlowList); KeInitializeSpinLock(&gFlowListLock); InitializeListHead(&gPacketQueue); KeInitializeSpinLock(&gPacketQueueLock); KeInitializeEvent( &gPacketQueueEvent, NotificationEvent, FALSE ); status = DDProxyRegisterCallouts( gDeviceObject ); if (!NT_SUCCESS(status)) { goto Exit; } status = PsCreateSystemThread( &threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, DDProxyWorker, NULL ); if (!NT_SUCCESS(status)) { goto Exit; } status = ObReferenceObjectByHandle( threadHandle, 0, NULL, KernelMode, &gThreadObj, NULL ); ASSERT(NT_SUCCESS(status)); ZwClose(threadHandle); driverObject->DriverUnload = DriverUnload; Exit: if (!NT_SUCCESS(status)) { if (gEngineHandle != NULL) { DDProxyUnregisterCallouts(); } if (gInjectionHandle != NULL) { FwpsInjectionHandleDestroy0(gInjectionHandle); } if (gDeviceObject) { IoDeleteDevice(gDeviceObject); } } return status; }
NTSTATUS NtQueryFullAttributesFile ( __in POBJECT_ATTRIBUTES ObjectAttributes, __out PFILE_NETWORK_OPEN_INFORMATION FileInformation ) /*++ Routine Description: This service queries the network attributes information for a specified file. Arguments: ObjectAttributes - Supplies the attributes to be used for file object (name, SECURITY_DESCRIPTOR, etc.) FileInformation - Supplies an output buffer to receive the returned file attributes information. Return Value: The status returned is the final completion status of the operation. --*/ { KPROCESSOR_MODE requestorMode; NTSTATUS status; OPEN_PACKET openPacket; DUMMY_FILE_OBJECT localFileObject; FILE_NETWORK_OPEN_INFORMATION networkInformation; HANDLE handle; PAGED_CODE(); // // Get the previous mode; i.e., the mode of the caller. // requestorMode = KeGetPreviousMode(); if (requestorMode != KernelMode) { try { // // The caller's mode is not kernel, so probe the output buffer. // ProbeForWriteSmallStructure( FileInformation, sizeof( FILE_NETWORK_OPEN_INFORMATION ), #if defined(_X86_) sizeof( LONG )); #else sizeof( LONGLONG )); #endif // defined(_X86_) } except(EXCEPTION_EXECUTE_HANDLER) { // // An exception was incurred while probing the caller's parameters. // Simply return an appropriate error status code. // return GetExceptionCode(); } } // // Build a parse open packet that tells the parse method to open the file, // query the file's full attributes, and close the file. // RtlZeroMemory( &openPacket, sizeof( OPEN_PACKET ) ); openPacket.Type = IO_TYPE_OPEN_PACKET; openPacket.Size = sizeof( OPEN_PACKET ); openPacket.ShareAccess = (USHORT) FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; openPacket.Disposition = FILE_OPEN; openPacket.CreateOptions = FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT; openPacket.QueryOnly = TRUE; openPacket.FullAttributes = TRUE; openPacket.TraversedMountPoint = FALSE; openPacket.LocalFileObject = &localFileObject; if (requestorMode != KernelMode) { openPacket.NetworkInformation = &networkInformation; } else { openPacket.NetworkInformation = FileInformation; } // // Update the open count for this process. // IopUpdateOtherOperationCount(); // // Open the object by its name. Because of the special QueryOnly flag set // in the open packet, the parse routine will open the file, and then // realize that it is only performing a query. It will therefore perform // the query, and immediately close the file. // status = ObOpenObjectByName( ObjectAttributes, (POBJECT_TYPE) NULL, requestorMode, NULL, FILE_READ_ATTRIBUTES, &openPacket, &handle ); // // The operation is successful if the parse check field of the open packet // indicates that the parse routine was actually invoked, and the final // status field of the packet is set to success. // if (openPacket.ParseCheck != OPEN_PACKET_PATTERN) { if (NT_SUCCESS(status)) { ZwClose(handle); status = STATUS_OBJECT_TYPE_MISMATCH; } return status; } else { status = openPacket.FinalStatus; } if (NT_SUCCESS( status )) { if (requestorMode != KernelMode) { try { // // The query worked, so copy the returned information to the // caller's output buffer. // RtlCopyMemory( FileInformation, &networkInformation, sizeof( FILE_NETWORK_OPEN_INFORMATION ) ); } except(EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); } } } return status; }
void DDProxyLoadConfig( IN PUNICODE_STRING registryPath ) { NTSTATUS status; OBJECT_ATTRIBUTES objectAttributes; HANDLE registryKey; UNICODE_STRING valueName; UCHAR regValueStorage[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + INET6_ADDRSTRLEN * sizeof(WCHAR)]; KEY_VALUE_PARTIAL_INFORMATION* regValue = (KEY_VALUE_PARTIAL_INFORMATION*)regValueStorage; ULONG resultLength; InitializeObjectAttributes( &objectAttributes, registryPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL ); status = ZwOpenKey( ®istryKey, KEY_READ, &objectAttributes ); if (NT_SUCCESS(status)) { RtlInitUnicodeString( &valueName, L"InspectUdp" ); status = ZwQueryValueKey( registryKey, &valueName, KeyValuePartialInformation, regValue, sizeof(regValueStorage), &resultLength ); if (NT_SUCCESS(status)) { if ((*(PULONG)regValue->Data) != 0) { configInspectUdp = TRUE; } else { configInspectUdp = FALSE; } } RtlInitUnicodeString( &valueName, L"DestinationAddressToIntercept" ); status = ZwQueryValueKey( registryKey, &valueName, KeyValuePartialInformation, regValue, sizeof(regValueStorage), &resultLength ); if (NT_SUCCESS(status)) { PWSTR terminator; status = RtlIpv4StringToAddressW( (PCWSTR)(regValue->Data), TRUE, &terminator, &destAddrStorageV4 ); if (NT_SUCCESS(status)) { destAddrStorageV4.S_un.S_addr = RtlUlongByteSwap(destAddrStorageV4.S_un.S_addr); configInspectDestAddrV4 = &destAddrStorageV4.S_un.S_un_b.s_b1; } else { status = RtlIpv6StringToAddressW( (PCWSTR)(regValue->Data), &terminator, &destAddrStorageV6 ); if (NT_SUCCESS(status)) { configInspectDestAddrV6 = (UINT8*)(&destAddrStorageV6.u.Byte[0]); } } } RtlInitUnicodeString( &valueName, L"DestinationPortToIntercept" ); status = ZwQueryValueKey( registryKey, &valueName, KeyValuePartialInformation, regValue, sizeof(regValueStorage), &resultLength ); if (NT_SUCCESS(status)) { configInspectDestPort = (USHORT)(*(PULONG)regValue->Data); } RtlInitUnicodeString( &valueName, L"NewDestinationAddress" ); status = ZwQueryValueKey( registryKey, &valueName, KeyValuePartialInformation, regValue, sizeof(regValueStorage), &resultLength ); if (NT_SUCCESS(status)) { PWSTR terminator; status = RtlIpv4StringToAddressW( (PCWSTR)(regValue->Data), TRUE, &terminator, &newDestAddrStorageV4 ); if (NT_SUCCESS(status)) { newDestAddrStorageV4.S_un.S_addr = RtlUlongByteSwap(newDestAddrStorageV4.S_un.S_addr); configNewDestAddrV4 = &newDestAddrStorageV4.S_un.S_un_b.s_b1; } else { status = RtlIpv6StringToAddressW( (PCWSTR)(regValue->Data), &terminator, &newDestAddrStorageV6 ); if (NT_SUCCESS(status)) { configNewDestAddrV6 = (UINT8*)(&newDestAddrStorageV6.u.Byte[0]); } } } RtlInitUnicodeString( &valueName, L"NewDestinationPort" ); status = ZwQueryValueKey( registryKey, &valueName, KeyValuePartialInformation, regValue, sizeof(regValueStorage), &resultLength ); if (NT_SUCCESS(status)) { configNewDestPort = (USHORT)(*(PULONG)regValue->Data); } ZwClose(registryKey); } }
BOOLEAN SeRmInitPhase1( ) /*++ Routine Description: This function is called by Phase 1 System Initialization to initialize the Security Reference Monitor. Note that initialization of the Reference Monitor Global State has already been performed in Phase 0 initialization to allow access validation routines to operate without having to check that Reference Monitor Initialization is complete. The steps listed below are performed in this routine. The remainder of Reference Monitor initialization requires the LSA subsystem to have run, so that initialization is performed in a separate thread (the RM Command Server Thread, see below), so that the present thread can create the Session Manager which execs the LSA. o Create the Reference Monitor Command LPC port. The LSA subsystem sends commands (e.g. turn on auditing) which change the Reference Monitor Global State. o Create an Event for use in synchronizing with the LSA subsystem. The LSA will signal the event when the portion of LSA initialization upon with the Reference Monitor depends is complete. The Reference Monitor uses another LPC port, called the LSA Command Port to send commands to the LSA, so the RM must know that this port has been created before trying to connect to it. o Create the Reference Monitor Command Server Thread. This thread is a permanent thread of the System Init process that fields the Reference Monitor State Change commands described above. Arguments: None. Return Value: BOOLEAN - TRUE if Rm Initialization (Phase 1) succeeded, else FALSE --*/ { NTSTATUS Status; STRING RmCommandPortName; UNICODE_STRING UnicodeRmCommandPortName; OBJECT_ATTRIBUTES ObjectAttributes; STRING LsaInitEventName; UNICODE_STRING UnicodeLsaInitEventName; OBJECT_ATTRIBUTES LsaInitEventObjectAttributes; SECURITY_DESCRIPTOR LsaInitEventSecurityDescriptor; ULONG AclSize; PAGED_CODE(); // // Create an LPC port called the Reference Monitor Command Port. // This will be used by the LSA to send commands to the Reference // Monitor to update its state data. // RtlInitString( &RmCommandPortName, "\\SeRmCommandPort" ); Status = RtlAnsiStringToUnicodeString( &UnicodeRmCommandPortName, &RmCommandPortName, TRUE ); ASSERT( NT_SUCCESS(Status) ); InitializeObjectAttributes( &ObjectAttributes, &UnicodeRmCommandPortName, 0, NULL, NULL ); Status = ZwCreatePort( &SepRmState.RmCommandPortHandle, &ObjectAttributes, sizeof(SEP_RM_CONNECT_INFO), sizeof(RM_COMMAND_MESSAGE), sizeof(RM_COMMAND_MESSAGE) * 32 ); RtlFreeUnicodeString( &UnicodeRmCommandPortName ); if( !NT_SUCCESS(Status) ) { KdPrint(("Security: Rm Create Command Port failed 0x%lx\n", Status)); return FALSE; } // // Prepare to create an event for synchronizing with the LSA. // First, build the Security Descriptor for the Init Event Object // Status = RtlCreateSecurityDescriptor( &LsaInitEventSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); if (!NT_SUCCESS(Status)) { KdPrint(("Security: Creating Lsa Init Event Desc failed 0x%lx\n", Status)); return FALSE; } // // Allocate a temporary buffer from the paged pool. It is a fatal // system error if the allocation fails since security cannot be // enabled. // AclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + SeLengthSid(SeLocalSystemSid); LsaInitEventSecurityDescriptor.Dacl = ExAllocatePoolWithTag(PagedPool, AclSize, 'cAeS'); if (LsaInitEventSecurityDescriptor.Dacl == NULL) { KdPrint(("Security LSA: Insufficient resources to initialize\n")); return FALSE; } // // Now create the Discretionary ACL within the Security Descriptor // Status = RtlCreateAcl( LsaInitEventSecurityDescriptor.Dacl, AclSize, ACL_REVISION2 ); if (!NT_SUCCESS(Status)) { KdPrint(("Security: Creating Lsa Init Event Dacl failed 0x%lx\n", Status)); return FALSE; } // // Now add an ACE giving GENERIC_ALL access to the User ID // Status = RtlAddAccessAllowedAce( LsaInitEventSecurityDescriptor.Dacl, ACL_REVISION2, GENERIC_ALL, SeLocalSystemSid ); if (!NT_SUCCESS(Status)) { KdPrint(("Security: Adding Lsa Init Event ACE failed 0x%lx\n", Status)); return FALSE; } // // Set up the Object Attributes for the Lsa Initialization Event // RtlInitString( &LsaInitEventName, "\\SeLsaInitEvent" ); Status = RtlAnsiStringToUnicodeString( &UnicodeLsaInitEventName, &LsaInitEventName, TRUE ); ASSERT( NT_SUCCESS(Status) ); InitializeObjectAttributes( &LsaInitEventObjectAttributes, &UnicodeLsaInitEventName, 0, NULL, &LsaInitEventSecurityDescriptor ); // // Create an event for use in synchronizing with the LSA. The LSA will // signal this event when LSA initialization has reached the point // where the LSA's Reference Monitor Server Port has been created. // Status = ZwCreateEvent( &(SepRmState.LsaInitEventHandle), EVENT_MODIFY_STATE, &LsaInitEventObjectAttributes, NotificationEvent, FALSE); RtlFreeUnicodeString( &UnicodeLsaInitEventName ); if (!NT_SUCCESS(Status)) { KdPrint(("Security: LSA init event creation failed.0x%xl\n", Status)); return FALSE; } // // Deallocate the pool memory used for the Init Event DACL // ExFreePool( LsaInitEventSecurityDescriptor.Dacl ); // // Create a permanent thread of the Sysinit Process, called the // Reference Monitor Server Thread. This thread is dedicated to // receiving Reference Monitor commands and dispatching them. // Status = PsCreateSystemThread( &SepRmState.SepRmThreadHandle, THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SET_INFORMATION, NULL, NULL, NULL, SepRmCommandServerThread, NULL ); if (!NT_SUCCESS(Status)) { KdPrint(("Security: Rm Server Thread creation failed 0x%lx\n", Status)); return FALSE; } // // Initialize data from the registry. This must go here because all other // Se initialization takes place before the registry is initialized. // SepAdtInitializeCrashOnFail(); SepAdtInitializePrivilegeAuditing(); SepAdtInitializeAuditingOptions(); // // Reference Monitor initialization is successful if we get to here. // ZwClose( SepRmState.SepRmThreadHandle ); SepRmState.SepRmThreadHandle = NULL; return TRUE; }
BOOLEAN SepRmCommandServerThreadInit( VOID ) /*++ Routine Description: This function performs initialization of the Reference Monitor Server thread. The following steps are performed. o Wait on the LSA signalling the event. When the event is signalled, the LSA has already created the LSA Command Server LPC Port o Close the LSA Init Event Handle. The event is not used again. o Listen for the LSA to connect to the Port o Accept the connection. o Connect to the LSA Command Server LPC Port Arguments: None. Return Value: --*/ { NTSTATUS Status; UNICODE_STRING LsaCommandPortName; PORT_MESSAGE ConnectionRequest; SECURITY_QUALITY_OF_SERVICE DynamicQos; OBJECT_ATTRIBUTES ObjectAttributes; PORT_VIEW ClientView; REMOTE_PORT_VIEW LsaClientView; BOOLEAN BooleanStatus = TRUE; PAGED_CODE(); // // Save a pointer to our process so we can get back into this process // to send commands to the LSA (using a handle to an LPC port created // below). // SepRmLsaCallProcess = PsGetCurrentProcess(); ObReferenceObject(SepRmLsaCallProcess); // // Wait on the LSA signalling the event. This means that the LSA // has created its command port, not that LSA initialization is // complete. // Status = ZwWaitForSingleObject( SepRmState.LsaInitEventHandle, FALSE, NULL); if ( !NT_SUCCESS(Status) ) { KdPrint(("Security Rm Init: Waiting for LSA Init Event failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Close the LSA Init Event Handle. The event is not used again. // ZwClose(SepRmState.LsaInitEventHandle); // // Listen for a connection to be made by the LSA to the Reference Monitor // Command Port. This connection will be made by the LSA process. // ConnectionRequest.u1.s1.TotalLength = sizeof(ConnectionRequest); ConnectionRequest.u1.s1.DataLength = (CSHORT)0; Status = ZwListenPort( SepRmState.RmCommandPortHandle, &ConnectionRequest ); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Listen to Command Port failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Obtain a handle to the LSA process for use when auditing. // InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL ); Status = ZwOpenProcess( &SepLsaHandle, PROCESS_VM_OPERATION | PROCESS_VM_WRITE, &ObjectAttributes, &ConnectionRequest.ClientId ); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Open Listen to Command Port failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Accept the connection made by the LSA process. // LsaClientView.Length = sizeof(LsaClientView); Status = ZwAcceptConnectPort( &SepRmState.RmCommandPortHandle, NULL, &ConnectionRequest, TRUE, NULL, &LsaClientView ); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Accept Connect to Command Port failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Complete the connection. // Status = ZwCompleteConnectPort(SepRmState.RmCommandPortHandle); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Complete Connect to Command Port failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Set up the security quality of service parameters to use over the // Lsa Command LPC port. Use the most efficient (least overhead) - which // is dynamic rather than static tracking. // DynamicQos.ImpersonationLevel = SecurityImpersonation; DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; DynamicQos.EffectiveOnly = TRUE; // // Create the section to be used as unnamed shared memory for // communication between the RM and LSA. // SepRmState.LsaCommandPortSectionSize.LowPart = PAGE_SIZE; SepRmState.LsaCommandPortSectionSize.HighPart = 0; Status = ZwCreateSection( &SepRmState.LsaCommandPortSectionHandle, SECTION_ALL_ACCESS, NULL, // ObjectAttributes &SepRmState.LsaCommandPortSectionSize, PAGE_READWRITE, SEC_COMMIT, NULL // FileHandle ); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Create Memory Section for LSA port failed: %X\n", Status)); goto RmCommandServerThreadInitError; } // // Set up for a call to NtConnectPort and connect to the LSA port. // This setup includes a description of the port memory section so that // the LPC connection logic can make the section visible to both the // client and server processes. // ClientView.Length = sizeof(ClientView); ClientView.SectionHandle = SepRmState.LsaCommandPortSectionHandle; ClientView.SectionOffset = 0; ClientView.ViewSize = SepRmState.LsaCommandPortSectionSize.LowPart; ClientView.ViewBase = 0; ClientView.ViewRemoteBase = 0; // // Set up the security quality of service parameters to use over the // port. Use dynamic tracking so that XACTSRV will impersonate the // user that we are impersonating when we call NtRequestWaitReplyPort. // If we used static tracking, XACTSRV would impersonate the context // when the connection is made. // DynamicQos.ImpersonationLevel = SecurityImpersonation; DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; DynamicQos.EffectiveOnly = TRUE; // // Connect to the Lsa Command LPC Port. This port is used to send // commands from the RM to the LSA. // RtlInitUnicodeString( &LsaCommandPortName, L"\\SeLsaCommandPort" ); Status = ZwConnectPort( &SepRmState.LsaCommandPortHandle, &LsaCommandPortName, &DynamicQos, &ClientView, NULL, // ServerView NULL, // MaxMessageLength NULL, // ConnectionInformation NULL // ConnectionInformationLength ); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Connect to LSA Port failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Store information about the section so that we can create pointers // meaningful to LSA. // SepRmState.RmViewPortMemory = ClientView.ViewBase; SepRmState.LsaCommandPortMemoryDelta = (LONG)((ULONG_PTR)ClientView.ViewRemoteBase - (ULONG_PTR) ClientView.ViewBase ); SepRmState.LsaViewPortMemory = ClientView.ViewRemoteBase; /* BugWarning - ScottBi - probably don't need the resource // // Create the resource serializing access to the port. This // resource prevents the port and the shared memory from being // deleted while worker threads are processing requests. // if ( !SepRmState.LsaCommandPortResourceInitialized ) { ExInitializeResource( &SepRmState.LsaCommandPortResource ); SepRmState.LsaCommandPortResourceInitialized = TRUE; } SepRmState.LsaCommandPortActive = TRUE; */ RmCommandServerThreadInitFinish: // // Dont need this section handle any more, even if returning // success. // if ( SepRmState.LsaCommandPortSectionHandle != NULL ) { NtClose( SepRmState.LsaCommandPortSectionHandle ); SepRmState.LsaCommandPortSectionHandle = NULL; } // // The Reference Monitor Thread has successfully initialized. // return BooleanStatus; RmCommandServerThreadInitError: if ( SepRmState.LsaCommandPortHandle != NULL ) { NtClose( SepRmState.LsaCommandPortHandle ); SepRmState.LsaCommandPortHandle = NULL; } BooleanStatus = FALSE; goto RmCommandServerThreadInitFinish; }
VOID NTAPI ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PPROTOCOL_BINDING Protocol) { /* * bind the protocol to all of its miniports * * open registry path * get list of devices from Bind key * call BindAdapterHandler for each */ OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING RegistryPath; WCHAR *RegistryPathStr, *DataPtr = NULL; NTSTATUS NtStatus; HANDLE DriverKeyHandle = NULL; PKEY_VALUE_PARTIAL_INFORMATION KeyInformation = NULL; PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics = &Protocol->Chars; UNICODE_STRING ValueName; ULONG ResultLength; PLIST_ENTRY CurrentEntry = NULL; RegistryPathStr = ExAllocatePoolWithTag(PagedPool, sizeof(SERVICES_KEY) + ProtocolCharacteristics->Name.Length + sizeof(LINKAGE_KEY), NDIS_TAG + __LINE__); if(!RegistryPathStr) { NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); *Status = NDIS_STATUS_RESOURCES; return; } wcscpy(RegistryPathStr, SERVICES_KEY); wcsncat(RegistryPathStr, ((WCHAR *)ProtocolCharacteristics->Name.Buffer), ProtocolCharacteristics->Name.Length / sizeof(WCHAR)); RegistryPathStr[wcslen(SERVICES_KEY)+ProtocolCharacteristics->Name.Length/sizeof(WCHAR)] = 0; wcscat(RegistryPathStr, LINKAGE_KEY); RtlInitUnicodeString(&RegistryPath, RegistryPathStr); NDIS_DbgPrint(MAX_TRACE, ("Opening configuration key: %wZ\n", &RegistryPath)); InitializeObjectAttributes(&ObjectAttributes, &RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL); NtStatus = ZwOpenKey(&DriverKeyHandle, KEY_READ, &ObjectAttributes); ExFreePool(RegistryPathStr); if(NT_SUCCESS(NtStatus)) { NDIS_DbgPrint(MAX_TRACE, ("Successfully opened the registry configuration\n")); RtlInitUnicodeString(&ValueName, L"Bind"); NtStatus = ZwQueryValueKey(DriverKeyHandle, &ValueName, KeyValuePartialInformation, NULL, 0, &ResultLength); if(NtStatus != STATUS_BUFFER_OVERFLOW && NtStatus != STATUS_BUFFER_TOO_SMALL && NtStatus != STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unable to query the Bind value for size\n")); ZwClose(DriverKeyHandle); } else { KeyInformation = ExAllocatePoolWithTag(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + ResultLength, NDIS_TAG + __LINE__); if(!KeyInformation) { NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); ZwClose(DriverKeyHandle); NtStatus = STATUS_NO_MEMORY; } else { NtStatus = ZwQueryValueKey(DriverKeyHandle, &ValueName, KeyValuePartialInformation, KeyInformation, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + ResultLength, &ResultLength); ZwClose(DriverKeyHandle); if(!NT_SUCCESS(NtStatus)) { NDIS_DbgPrint(MIN_TRACE, ("Unable to query the Bind value\n")); ExFreePool(KeyInformation); KeyInformation = NULL; } } } } if (!NT_SUCCESS(NtStatus)) { NDIS_DbgPrint(MID_TRACE, ("Performing global bind for protocol '%wZ'\n", &ProtocolCharacteristics->Name)); KeyInformation = NULL; CurrentEntry = AdapterListHead.Flink; } else { NDIS_DbgPrint(MID_TRACE, ("Performing standard bind for protocol '%wZ'\n", &ProtocolCharacteristics->Name)); DataPtr = (WCHAR*)KeyInformation->Data; } /* Assume success for now */ *Status = NDIS_STATUS_SUCCESS; while (TRUE) { /* BindContext is for tracking pending binding operations */ VOID *BindContext = 0; NDIS_STRING DeviceName; NDIS_STRING RegistryPath; WCHAR *RegistryPathStr = NULL; ULONG PathLength = 0; PLOGICAL_ADAPTER Adapter; if (KeyInformation) { /* Parse the REG_MULTI_SZ entry for device names */ if (!(*DataPtr)) break; RtlInitUnicodeString(&DeviceName, DataPtr); } else { /* Use the device name from the global adapter list */ if (CurrentEntry == &AdapterListHead) break; Adapter = CONTAINING_RECORD(CurrentEntry, LOGICAL_ADAPTER, ListEntry); DeviceName = Adapter->NdisMiniportBlock.MiniportName; } /* Make sure the adapter has started */ if (!MiniLocateDevice(&DeviceName)) { /* It wasn't in the global miniport list, so skip the bind entry */ goto next; } /* Make sure this device isn't already bound to this protocol */ if (LocateAdapterBindingByName(Protocol, &DeviceName)) { /* It was already in this protocol's bound adapter list, so skip the bind entry */ goto next; } /* * RegistryPath should be: * \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip * * This is constructed as follows: * SERVICES_KEY + extracted device name + Protocol name from characteristics */ PathLength = sizeof(SERVICES_KEY) + /* \Registry\Machine\System\CurrentControlSet\Services\ */ wcslen( DeviceName.Buffer + 8 ) * sizeof(WCHAR) + /* Adapter1 (extracted from \Device\Adapter1) */ sizeof(PARAMETERS_KEY) + /* \Parameters\ */ ProtocolCharacteristics->Name.Length + sizeof(WCHAR); /* Tcpip */ RegistryPathStr = ExAllocatePool(PagedPool, PathLength); if(!RegistryPathStr) { NDIS_DbgPrint(MIN_TRACE, ("insufficient resources.\n")); *Status = NDIS_STATUS_RESOURCES; break; } wcscpy(RegistryPathStr, SERVICES_KEY); wcscat(RegistryPathStr, DeviceName.Buffer + 8 ); wcscat(RegistryPathStr, PARAMETERS_KEY); wcsncat(RegistryPathStr, ProtocolCharacteristics->Name.Buffer, ProtocolCharacteristics->Name.Length / sizeof(WCHAR) ); RegistryPathStr[PathLength/sizeof(WCHAR) - 1] = 0; RtlInitUnicodeString(&RegistryPath, RegistryPathStr); NDIS_DbgPrint(MAX_TRACE, ("Calling protocol's BindAdapter handler with DeviceName %wZ and RegistryPath %wZ\n", &DeviceName, &RegistryPath)); { BIND_HANDLER BindHandler = ProtocolCharacteristics->BindAdapterHandler; if(BindHandler) { BindHandler(Status, BindContext, &DeviceName, &RegistryPath, 0); NDIS_DbgPrint(MID_TRACE, ("%wZ's BindAdapter handler returned 0x%x for %wZ\n", &ProtocolCharacteristics->Name, *Status, &DeviceName)); } else NDIS_DbgPrint(MID_TRACE, ("No protocol bind handler specified\n")); } next: if (KeyInformation) { /* Advance to the next adapter in the REG_MULTI_SZ */ DataPtr += (DeviceName.Length / sizeof(WCHAR)) + 1; } else { /* Advance to the next adapter in the global list */ CurrentEntry = CurrentEntry->Flink; } } if (KeyInformation) { ExFreePool(KeyInformation); } }
NTSTATUS FatGetCompatibilityModeValue ( IN PUNICODE_STRING ValueName, IN OUT PULONG Value ) /*++ Routine Description: Given a unicode value name this routine will go into the registry location for the Chicago compatibilitymode information and get the value. Arguments: ValueName - the unicode name for the registry value located in the registry. Value - a pointer to the ULONG for the result. Return Value: NTSTATUS If STATUS_SUCCESSFUL is returned, the location *Value will be updated with the DWORD value from the registry. If any failing status is returned, this value is untouched. --*/ { HANDLE Handle; NTSTATUS Status; ULONG RequestLength; ULONG ResultLength; UCHAR Buffer[KEY_WORK_AREA]; UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; PKEY_VALUE_FULL_INFORMATION KeyValueInformation; KeyName.Buffer = COMPATIBILITY_MODE_KEY_NAME; KeyName.Length = sizeof(COMPATIBILITY_MODE_KEY_NAME) - sizeof(WCHAR); KeyName.MaximumLength = sizeof(COMPATIBILITY_MODE_KEY_NAME); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&Handle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { return Status; } RequestLength = KEY_WORK_AREA; KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)Buffer; while (1) { Status = ZwQueryValueKey(Handle, ValueName, KeyValueFullInformation, KeyValueInformation, RequestLength, &ResultLength); NT_ASSERT( Status != STATUS_BUFFER_OVERFLOW ); if (Status == STATUS_BUFFER_OVERFLOW) { // // Try to get a buffer big enough. // if (KeyValueInformation != (PKEY_VALUE_FULL_INFORMATION)Buffer) { ExFreePool(KeyValueInformation); } RequestLength += 256; KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION) ExAllocatePoolWithTag(PagedPool, RequestLength, ' taF'); if (!KeyValueInformation) { ZwClose(Handle); return STATUS_NO_MEMORY; } } else { break; } } ZwClose(Handle); if (NT_SUCCESS(Status)) { if (KeyValueInformation->DataLength != 0) { PULONG DataPtr; // // Return contents to the caller. // DataPtr = (PULONG) ((PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset); *Value = *DataPtr; } else { // // Treat as if no value was found // Status = STATUS_OBJECT_NAME_NOT_FOUND; } } if (KeyValueInformation != (PKEY_VALUE_FULL_INFORMATION)Buffer) { ExFreePool(KeyValueInformation); } return Status; }
int FlQueueIrpToThread(int Irp , int DisketteExtension ) { int status ; int threadHandle = __VERIFIER_nondet_int() ; int DisketteExtension__PoweringDown = __VERIFIER_nondet_int() ; int DisketteExtension__ThreadReferenceCount = __VERIFIER_nondet_int() ; int DisketteExtension__FloppyThread = __VERIFIER_nondet_int() ; int Irp__IoStatus__Status ; int Irp__IoStatus__Information ; int Irp__Tail__Overlay__CurrentStackLocation__Control ; int ObjAttributes = __VERIFIER_nondet_int() ; int __cil_tmp12 ; int __cil_tmp13 ; { if (DisketteExtension__PoweringDown == 1) { myStatus = -1073741101; Irp__IoStatus__Status = -1073741101; Irp__IoStatus__Information = 0; return (-1073741101); } DisketteExtension__ThreadReferenceCount ++; if (DisketteExtension__ThreadReferenceCount == 0) { DisketteExtension__ThreadReferenceCount ++; PagingReferenceCount ++; if (PagingReferenceCount == 1) { } { status = PsCreateSystemThread(threadHandle, 0, ObjAttributes, 0, 0, FloppyThread, DisketteExtension); } { if (status < 0) { DisketteExtension__ThreadReferenceCount = -1; PagingReferenceCount --; if (PagingReferenceCount == 0) { } return (status); } } { status = ObReferenceObjectByHandle(threadHandle, 1048576, 0, KernelMode, DisketteExtension__FloppyThread, 0); ZwClose(threadHandle); } { if (status < 0) { return (status); } } } // Irp__Tail__Overlay__CurrentStackLocation__Control |= 1; if (pended == 0) { pended = 1; } else { { errorFn(); } } return (259); } }
BOOLEAN FatIsFujitsuFMR ( ) /*++ Routine Description: This routine tells if is we running on a FujitsuFMR machine. Arguments: Return Value: BOOLEAN - TRUE is we are and FALSE otherwise --*/ { BOOLEAN Result; HANDLE Handle; NTSTATUS Status; ULONG RequestLength; ULONG ResultLength; UCHAR Buffer[KEY_WORK_AREA]; UNICODE_STRING KeyName; UNICODE_STRING ValueName; OBJECT_ATTRIBUTES ObjectAttributes; PKEY_VALUE_FULL_INFORMATION KeyValueInformation; // // Set default as PC/AT // KeyName.Buffer = REGISTRY_HARDWARE_DESCRIPTION_W; KeyName.Length = sizeof(REGISTRY_HARDWARE_DESCRIPTION_W) - sizeof(WCHAR); KeyName.MaximumLength = sizeof(REGISTRY_HARDWARE_DESCRIPTION_W); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&Handle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { return FALSE; } ValueName.Buffer = REGISTRY_MACHINE_IDENTIFIER_W; ValueName.Length = sizeof(REGISTRY_MACHINE_IDENTIFIER_W) - sizeof(WCHAR); ValueName.MaximumLength = sizeof(REGISTRY_MACHINE_IDENTIFIER_W); RequestLength = KEY_WORK_AREA; KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)Buffer; while (1) { Status = ZwQueryValueKey(Handle, &ValueName, KeyValueFullInformation, KeyValueInformation, RequestLength, &ResultLength); // NT_ASSERT( Status != STATUS_BUFFER_OVERFLOW ); if (Status == STATUS_BUFFER_OVERFLOW) { // // Try to get a buffer big enough. // if (KeyValueInformation != (PKEY_VALUE_FULL_INFORMATION)Buffer) { ExFreePool(KeyValueInformation); } RequestLength += 256; KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION) ExAllocatePoolWithTag(PagedPool, RequestLength, ' taF'); if (!KeyValueInformation) { ZwClose(Handle); return FALSE; } } else { break; } } ZwClose(Handle); if (NT_SUCCESS(Status) && (KeyValueInformation->DataLength >= sizeof(FUJITSU_FMR_NAME_W)) && (RtlCompareMemory((PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset, FUJITSU_FMR_NAME_W, sizeof(FUJITSU_FMR_NAME_W) - sizeof(WCHAR)) == sizeof(FUJITSU_FMR_NAME_W) - sizeof(WCHAR))) { Result = TRUE; } else { Result = FALSE; } if (KeyValueInformation != (PKEY_VALUE_FULL_INFORMATION)Buffer) { ExFreePool(KeyValueInformation); } return Result; }
VOID NTAPI ClassGetDeviceParameter( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PWSTR SubkeyName OPTIONAL, IN PWSTR ParameterName, IN OUT PULONG ParameterValue // also default value ) { NTSTATUS status; RTL_QUERY_REGISTRY_TABLE queryTable[2]; HANDLE deviceParameterHandle; HANDLE deviceSubkeyHandle; ULONG defaultParameterValue; PAGED_CODE(); // // open the given parameter // status = IoOpenDeviceRegistryKey(FdoExtension->LowerPdo, PLUGPLAY_REGKEY_DEVICE, KEY_READ, &deviceParameterHandle); if (NT_SUCCESS(status) && (SubkeyName != NULL)) { UNICODE_STRING subkeyName; OBJECT_ATTRIBUTES objectAttributes; RtlInitUnicodeString(&subkeyName, SubkeyName); InitializeObjectAttributes(&objectAttributes, &subkeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, deviceParameterHandle, NULL); status = ZwOpenKey(&deviceSubkeyHandle, KEY_READ, &objectAttributes); if (!NT_SUCCESS(status)) { ZwClose(deviceParameterHandle); } } if (NT_SUCCESS(status)) { RtlZeroMemory(queryTable, sizeof(queryTable)); defaultParameterValue = *ParameterValue; queryTable->Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; queryTable->Name = ParameterName; queryTable->EntryContext = ParameterValue; queryTable->DefaultType = REG_DWORD; queryTable->DefaultData = NULL; queryTable->DefaultLength = 0; status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, (PWSTR)(SubkeyName ? deviceSubkeyHandle : deviceParameterHandle), queryTable, NULL, NULL); if (!NT_SUCCESS(status)) { *ParameterValue = defaultParameterValue; // use default value } // // close what we open // if (SubkeyName) { ZwClose(deviceSubkeyHandle); } ZwClose(deviceParameterHandle); } return; } // end ClassGetDeviceParameter()
/////////////////////////////////////////////////////////////////////////////////// // // 功能实现:枚举Csrss.exe进程PID // 输入参数:无 // 输出参数:返回Csrss.exe进程的PID // /////////////////////////////////////////////////////////////////////////////////// HANDLE GetCsrssPid() { NTSTATUS ntStatus; HANDLE hProc, hObject; HANDLE CsrssPid = (HANDLE)0; OBJECT_ATTRIBUTES objAttr; CLIENT_ID cid; int i; UNICODE_STRING ApiPortName; POBJECT_NAME_INFORMATION ObjName; PSYSTEM_HANDLE_INFORMATION_EX Handles; RtlInitUnicodeString( &ApiPortName, L"\\Windows\\ApiPort" ); //获取句柄信息 Handles = GetInfoTable( SystemHandleInformation ); if( Handles == NULL ) { DbgPrint("[GetCsrssPid]->GetInfoTable() Error\n"); return 0; } ObjName = ExAllocatePool( PagedPool, 0x2000 ); for( i = 0; i != Handles->NumberOfHandles; i++ ) { if ( Handles->Information[i].ObjectTypeNumber == 21 ) //Port object,Win2kSP1下找不到21端口 { InitializeObjectAttributes( &objAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL ); cid.UniqueProcess = (HANDLE)Handles->Information[i].ProcessId; cid.UniqueThread = 0; //打开进程 ntStatus = ZwOpenProcess( &hProc, PROCESS_DUP_HANDLE, &objAttr, &cid ); if( NT_SUCCESS(ntStatus) ) { //复制句柄 ntStatus = ZwDuplicateObject( hProc, (HANDLE)Handles->Information[i].Handle, NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS ); if( NT_SUCCESS(ntStatus) ) { //查询对象 ntStatus = ZwQueryObject( hObject, ObjectNameInformation, ObjName, 0x2000, NULL); if( NT_SUCCESS(ntStatus) ) { if (ObjName->Name.Buffer != NULL) { if ( wcsncmp( ApiPortName.Buffer, ObjName->Name.Buffer, 20 ) == 0 ) { //获取Csrss.exe进程Pid CsrssPid = (HANDLE)Handles->Information[i].ProcessId; ZwClose( hProc ); ZwClose( hObject ); IxExFreePool( Handles ); IxExFreePool( ObjName ); return CsrssPid; } } } else DbgPrint("Error in Query Object\n"); ZwClose(hObject); } else DbgPrint("Error on duplicating object\n"); ZwClose(hProc); } else DbgPrint("Could not open process\n"); } } IxExFreePool( Handles ); IxExFreePool( ObjName ); return 0; }
/** * Find and hot-swap to a backing file. Internal. * * We search all filesystems for a particular filename, then swap * to using it as the backing store. This is currently useful for * sector-mapped disks which should really have a file-in-use lock * for the file they represent. Once the backing file is established, * the work item is freed. Otherwise, it is re-enqueued and the * thread will keep trying. */ static BOOLEAN STDCALL WvFilediskHotSwap_( IN WV_SP_FILEDISK_T filedisk, IN PUNICODE_STRING filename ) { NTSTATUS status; GUID vol_guid = GUID_DEVINTERFACE_VOLUME; PWSTR sym_links; PWCHAR pos; KIRQL irql; /* Do we currently have a backing disk? If not, re-enqueue for later. */ if (filedisk->file == NULL) return FALSE; /* * Find the backing volume and use it. We walk a list * of unicode volume device names and check each one for the file. */ status = IoGetDeviceInterfaces(&vol_guid, NULL, 0, &sym_links); if (!NT_SUCCESS(status)) return FALSE; pos = sym_links; status = STATUS_UNSUCCESSFUL; while (*pos != UNICODE_NULL) { UNICODE_STRING path; PFILE_OBJECT vol_file_obj; PDEVICE_OBJECT vol_dev_obj; UNICODE_STRING vol_dos_name; UNICODE_STRING filepath; static const WCHAR obj_path_prefix[] = L"\\??\\"; static const WCHAR path_sep = L'\\'; OBJECT_ATTRIBUTES obj_attrs; HANDLE file = 0; IO_STATUS_BLOCK io_status; RtlInitUnicodeString(&path, pos); /* Get some object pointers for the volume. */ status = IoGetDeviceObjectPointer( &path, FILE_READ_DATA, &vol_file_obj, &vol_dev_obj ); if (!NT_SUCCESS(status)) goto err_obj_ptrs; /* Get the DOS name. */ vol_dos_name.Buffer = NULL; vol_dos_name.Length = vol_dos_name.MaximumLength = 0; status = RtlVolumeDeviceToDosName( vol_file_obj->DeviceObject, &vol_dos_name ); if (!NT_SUCCESS(status)) goto err_dos_name; /* Build the file path. Ugh, what a mess. */ filepath.Length = filepath.MaximumLength = sizeof obj_path_prefix - sizeof UNICODE_NULL + vol_dos_name.Length + sizeof path_sep + filename->Length; filepath.Buffer = wv_malloc(filepath.Length); if (filepath.Buffer == NULL) { status = STATUS_UNSUCCESSFUL; goto err_alloc_buf; } { PCHAR buf = (PCHAR) filepath.Buffer; RtlCopyMemory( buf, obj_path_prefix, sizeof obj_path_prefix - sizeof UNICODE_NULL ); buf += sizeof obj_path_prefix - sizeof UNICODE_NULL; RtlCopyMemory(buf, vol_dos_name.Buffer, vol_dos_name.Length); buf += vol_dos_name.Length; RtlCopyMemory(buf, &path_sep, sizeof path_sep); buf += sizeof path_sep; RtlCopyMemory(buf, filename->Buffer, filename->Length); } /* buf scope */ InitializeObjectAttributes( &obj_attrs, &filepath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL ); /* Look for the file on this volume. */ status = ZwCreateFile( &file, GENERIC_READ | GENERIC_WRITE, &obj_attrs, &io_status, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if (!NT_SUCCESS(status)) goto err_open; /* We could open it. Do the hot-swap. */ { HANDLE old = filedisk->file; filedisk->file = 0; filedisk->offset.QuadPart = 0; filedisk->file = file; ZwClose(old); } /* old scope */ err_open: wv_free(filepath.Buffer); err_alloc_buf: wv_free(vol_dos_name.Buffer); err_dos_name: ObDereferenceObject(vol_file_obj); err_obj_ptrs: /* Walk to the next terminator. */ while (*pos != UNICODE_NULL) pos++; /* If everything succeeded, stop. Otherwise try the next volume. */ if (!NT_SUCCESS(status)) pos++; } /* while */ wv_free(sym_links); /* Success? */ if (NT_SUCCESS(status)) { DBG("Finished hot-swapping.\n"); return TRUE; } return FALSE; }
// // Query information on LanscsiBus // NTSTATUS LSBus_QueryInformation( PFDO_DEVICE_DATA FdoData, PBUSENUM_QUERY_INFORMATION Query, PBUSENUM_INFORMATION Information, LONG OutBufferLength, PLONG OutBufferLenNeeded ) { NTSTATUS ntStatus; PLIST_ENTRY entry; PPDO_DEVICE_DATA PdoData; ntStatus = STATUS_SUCCESS; *OutBufferLenNeeded = OutBufferLength; PdoData = NULL; // // Acquire the mutex to prevent PdoData ( Device Extension ) to disappear. // KeEnterCriticalRegion(); ExAcquireFastMutex (&FdoData->Mutex); switch(Query->InfoClass) { case INFORMATION_NUMOFPDOS: { ULONG NumOfPDOs; NumOfPDOs = 0; for (entry = FdoData->ListOfPDOs.Flink; entry != &FdoData->ListOfPDOs; entry = entry->Flink) { NumOfPDOs ++; } Information->NumberOfPDOs = NumOfPDOs; break; } case INFORMATION_PDO: { KIRQL oldIrql; for (entry = FdoData->ListOfPDOs.Flink; entry != &FdoData->ListOfPDOs; entry = entry->Flink) { PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link); if(Query->SlotNo == PdoData->SlotNo) { ObReferenceObject(PdoData->Self); break; } PdoData = NULL; } if(PdoData) { KeAcquireSpinLock(&PdoData->LanscsiAdapterPDO.LSDevDataSpinLock, &oldIrql); Bus_KdPrint_Def(BUS_DBG_SS_TRACE, ("Status:%08lx DAcc:%08lx GAcc:%08lx\n", PdoData->LanscsiAdapterPDO.AdapterStatus, PdoData->LanscsiAdapterPDO.DesiredAccess, PdoData->LanscsiAdapterPDO.GrantedAccess )); Information->PdoInfo.AdapterStatus = PdoData->LanscsiAdapterPDO.AdapterStatus; Information->PdoInfo.DesiredAccess = PdoData->LanscsiAdapterPDO.DesiredAccess; Information->PdoInfo.GrantedAccess = PdoData->LanscsiAdapterPDO.GrantedAccess; KeReleaseSpinLock(&PdoData->LanscsiAdapterPDO.LSDevDataSpinLock, oldIrql); ObDereferenceObject(PdoData->Self); } else { Bus_KdPrint_Def(BUS_DBG_SS_NOISE, ("No PDO for SlotNo %d!\n", Query->SlotNo)); ntStatus = STATUS_NO_SUCH_DEVICE; } break; } case INFORMATION_PDOENUM: { LARGE_INTEGER TimeOut; for (entry = FdoData->ListOfPDOs.Flink; entry != &FdoData->ListOfPDOs; entry = entry->Flink) { PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link); if(Query->SlotNo == PdoData->SlotNo) { ObReferenceObject(PdoData->Self); break; } PdoData = NULL; } ExReleaseFastMutex (&FdoData->Mutex); KeLeaveCriticalRegion(); if(!PdoData) { KeEnterCriticalRegion(); ExAcquireFastMutex (&FdoData->Mutex); ntStatus = STATUS_NO_SUCH_DEVICE; break; } // // Wait until LDServ sends AddTargetData. // Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("waiting for AddTargetEvent.\n")); TimeOut.QuadPart = -10 * 1000 * 1000 * 120; // 120 seconds ntStatus = KeWaitForSingleObject( &PdoData->LanscsiAdapterPDO.AddTargetEvent, Executive, KernelMode, FALSE, &TimeOut ); if(ntStatus != STATUS_SUCCESS) { KeEnterCriticalRegion(); ExAcquireFastMutex (&FdoData->Mutex); Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("failed to wait for AddTargetEvent.\n")); ntStatus = STATUS_NO_SUCH_DEVICE; ObDereferenceObject(PdoData->Self); break; } Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Completed to wait for AddTargetEvent.\n")); KeEnterCriticalRegion(); ExAcquireFastMutex (&FdoData->Mutex); if(PdoData) { if(PdoData->LanscsiAdapterPDO.Flags & LSDEVDATA_FLAG_LURDESC) { // // A LUR descriptor is set. // if(PdoData->LanscsiAdapterPDO.AddDevInfo == NULL) { ntStatus = STATUS_NO_SUCH_DEVICE; ObDereferenceObject(PdoData->Self); break; } *OutBufferLenNeeded = FIELD_OFFSET(BUSENUM_INFORMATION, PdoEnumInfo) + FIELD_OFFSET(BUSENUM_INFORMATION_PDOENUM, AddDevInfo) + PdoData->LanscsiAdapterPDO.AddDevInfoLength; if(OutBufferLength < *OutBufferLenNeeded) { ntStatus = STATUS_BUFFER_TOO_SMALL; } else { RtlCopyMemory( &Information->PdoEnumInfo.AddDevInfo, PdoData->LanscsiAdapterPDO.AddDevInfo, PdoData->LanscsiAdapterPDO.AddDevInfoLength ); Information->PdoEnumInfo.Flags = PDOENUM_FLAG_LURDESC; Information->PdoEnumInfo.DisconEventToService = PdoData->LanscsiAdapterPDO.DisconEventToService; Information->PdoEnumInfo.AlarmEventToService = PdoData->LanscsiAdapterPDO.AlarmEventToService; Information->PdoEnumInfo.MaxBlocksPerRequest = PdoData->LanscsiAdapterPDO.MaxBlocksPerRequest; } } else { // // ADD_TARGET_DATA is set. // PLANSCSI_ADD_TARGET_DATA AddTargetData; LONG AddTargetLenNeeded; LONG InfoBuffLenNeeded; AddTargetData = PdoData->LanscsiAdapterPDO.AddDevInfo; if(AddTargetData == NULL) { ntStatus = STATUS_NO_SUCH_DEVICE; ObDereferenceObject(PdoData->Self); break; } // // calculate the length needed. // AddTargetLenNeeded = sizeof(LANSCSI_ADD_TARGET_DATA) + (AddTargetData->ulNumberOfUnitDiskList-1)*sizeof(LSBUS_UNITDISK); InfoBuffLenNeeded = sizeof(BUSENUM_INFORMATION) - sizeof(BYTE) + (AddTargetLenNeeded); *OutBufferLenNeeded = InfoBuffLenNeeded; if(OutBufferLength < InfoBuffLenNeeded) { ntStatus = STATUS_BUFFER_TOO_SMALL; } else { RtlCopyMemory(&Information->PdoEnumInfo.AddDevInfo, AddTargetData, AddTargetLenNeeded); Information->PdoEnumInfo.Flags = 0; Information->PdoEnumInfo.DisconEventToService = PdoData->LanscsiAdapterPDO.DisconEventToService; Information->PdoEnumInfo.AlarmEventToService = PdoData->LanscsiAdapterPDO.AlarmEventToService; Information->PdoEnumInfo.MaxBlocksPerRequest = PdoData->LanscsiAdapterPDO.MaxBlocksPerRequest; } } } else { ntStatus = STATUS_NO_SUCH_DEVICE; } ObDereferenceObject(PdoData->Self); break; } case INFORMATION_PDOEVENT: { for (entry = FdoData->ListOfPDOs.Flink; entry != &FdoData->ListOfPDOs; entry = entry->Flink) { PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link); if(Query->SlotNo == PdoData->SlotNo) { ObReferenceObject(PdoData->Self); break; } PdoData = NULL; } if(PdoData == NULL) { Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not find the PDO:%u.\n", Query->SlotNo)); ntStatus = STATUS_NO_SUCH_DEVICE; break; } if( Query->Flags & LSBUS_QUERYFLAG_USERHANDLE) { Information->PdoEvents.SlotNo = PdoData->SlotNo; Information->PdoEvents.Flags = LSBUS_QUERYFLAG_USERHANDLE; // // Get user-mode event handles. // ntStatus = ObOpenObjectByPointer( PdoData->LanscsiAdapterPDO.DisconEventToService, 0, NULL, GENERIC_READ, *ExEventObjectType, UserMode, &Information->PdoEvents.DisconEvent ); if(!NT_SUCCESS(ntStatus)) { ObDereferenceObject(PdoData->Self); Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not open Disconnect event object!!\n")); break; } ntStatus = ObOpenObjectByPointer( PdoData->LanscsiAdapterPDO.AlarmEventToService, 0, NULL, GENERIC_READ, *ExEventObjectType, UserMode, &Information->PdoEvents.AlarmEvent ); if(!NT_SUCCESS(ntStatus)) { ObDereferenceObject(PdoData->Self); Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not open Disconnect event object!!\n")); break; } } else { Information->PdoEvents.SlotNo = PdoData->SlotNo; Information->PdoEvents.Flags = 0; Information->PdoEvents.DisconEvent = PdoData->LanscsiAdapterPDO.DisconEventToService; Information->PdoEvents.AlarmEvent = PdoData->LanscsiAdapterPDO.AlarmEventToService; } ObDereferenceObject(PdoData->Self); break; } case INFORMATION_ISREGISTERED: { HANDLE DeviceReg; HANDLE NdasDeviceReg; ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); DeviceReg = NULL; NdasDeviceReg = NULL; ntStatus = Reg_OpenDeviceRegistry(FdoData->UnderlyingPDO, &DeviceReg, KEY_READ|KEY_WRITE); if(!NT_SUCCESS(ntStatus)) { Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("ISREGISTERED: OpenServiceRegistry() failed.\n")); break; } ntStatus = Reg_OpenNdasDeviceRegistry(&NdasDeviceReg, KEY_READ|KEY_WRITE, DeviceReg); if(!NT_SUCCESS(ntStatus)) { ZwClose(DeviceReg); Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("ISREGISTERED: OpenNdasDeviceRegistry() failed.\n")); break; } ntStatus = Reg_LookupRegDeviceWithSlotNo(NdasDeviceReg, Query->SlotNo, &DeviceReg); if(NT_SUCCESS(ntStatus)) { ZwClose(DeviceReg); Information->IsRegistered = 1; Bus_KdPrint_Def(BUS_DBG_SS_INFO, ("ISREGISTERED: Device(%d) is registered.\n", Query->SlotNo)); } else { Information->IsRegistered = 0; Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("ISREGISTERED: Could not find a Device(%d).\n", Query->SlotNo)); } if(NdasDeviceReg) ZwClose(NdasDeviceReg); if(DeviceReg) ZwClose(DeviceReg); break; } case INFORMATION_PDOSLOTLIST: { LONG outputLength; LONG entryCnt; if(OutBufferLength < FIELD_OFFSET(BUSENUM_INFORMATION, PdoSlotList)) { Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Buffer size is less than required\n")); ntStatus = STATUS_INVALID_PARAMETER; break; } Information->Size = 0; Information->InfoClass = INFORMATION_PDOSLOTLIST; // // Add the size of information header. // outputLength = FIELD_OFFSET(BUSENUM_INFORMATION, PdoSlotList); outputLength += sizeof(UINT32); // SlotNoCnt entryCnt = 0; for (entry = FdoData->ListOfPDOs.Flink; entry != &FdoData->ListOfPDOs; entry = entry->Flink) { PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link); // // Add the size of each slot entry. // outputLength += sizeof(UINT32); if(outputLength > OutBufferLength) { continue; } Information->PdoSlotList.SlotNo[entryCnt] = PdoData->SlotNo; Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Entry #%u: %u\n", entryCnt, PdoData->SlotNo)); entryCnt ++; } if(outputLength > OutBufferLength) { Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Could not find a Device(%d).\n", Query->SlotNo)); *OutBufferLenNeeded = outputLength; ntStatus = STATUS_BUFFER_TOO_SMALL; } else { Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Entry count:%d.\n", entryCnt)); Information->Size = outputLength; Information->PdoSlotList.SlotNoCnt = entryCnt; *OutBufferLenNeeded = outputLength; } break; } default: ntStatus = STATUS_INVALID_PARAMETER; } ExReleaseFastMutex (&FdoData->Mutex); KeLeaveCriticalRegion(); return ntStatus; }
NTSTATUS LpxTdiOpenConnection ( OUT PHANDLE ConnectionFileHandle, OUT PFILE_OBJECT *ConnectionFileObject, IN PVOID ConnectionContext ) { HANDLE connectionFileHandle; PFILE_OBJECT connectionFileObject; UNICODE_STRING nameString; OBJECT_ATTRIBUTES objectAttributes; UCHAR eaFullBuffer[CONNECTION_EA_BUFFER_LENGTH]; PFILE_FULL_EA_INFORMATION eaBuffer = (PFILE_FULL_EA_INFORMATION)eaFullBuffer; INT i; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; LtDebugPrint (3, ("[LpxTdi] LpxTdiOpenConnection: Entered\n")); // // Init object attributes // RtlInitUnicodeString (&nameString, TRANSPORT_NAME); InitializeObjectAttributes ( &objectAttributes, &nameString, 0, NULL, NULL ); RtlZeroMemory(eaBuffer, CONNECTION_EA_BUFFER_LENGTH); eaBuffer->NextEntryOffset = 0; eaBuffer->Flags = 0; eaBuffer->EaNameLength = TDI_CONNECTION_CONTEXT_LENGTH; eaBuffer->EaValueLength = sizeof (PVOID); for (i=0;i<(int)eaBuffer->EaNameLength;i++) { eaBuffer->EaName[i] = TdiConnectionContext[i]; } RtlMoveMemory ( &eaBuffer->EaName[TDI_CONNECTION_CONTEXT_LENGTH+1], &ConnectionContext, sizeof (PVOID) ); status = ZwCreateFile( &connectionFileHandle, GENERIC_READ, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, 0, 0, eaBuffer, CONNECTION_EA_BUFFER_LENGTH ); if (!NT_SUCCESS(status)) { LtDebugPrint (0, ("[LpxTdi] TdiOpenConnection: FAILURE, NtCreateFile returned status code=%x\n", status)); *ConnectionFileHandle = NULL; *ConnectionFileObject = NULL; return status; } status = ioStatusBlock.Status; if (!NT_SUCCESS(status)) { LtDebugPrint (0, ("[LpxTdi] TdiOpenConnection: FAILURE, IoStatusBlock.Status contains status code=%x\n", status)); *ConnectionFileHandle = NULL; *ConnectionFileObject = NULL; return status; } status = ObReferenceObjectByHandle ( connectionFileHandle, 0L, NULL, KernelMode, (PVOID *) &connectionFileObject, NULL ); if (!NT_SUCCESS(status)) { LtDebugPrint(0, ("[LpxTdi] TdiOpenConnection: ObReferenceObjectByHandle() FAILED %x\n", status)); ZwClose(connectionFileHandle); *ConnectionFileHandle = NULL; *ConnectionFileObject = NULL; return status; } *ConnectionFileHandle = connectionFileHandle; *ConnectionFileObject = connectionFileObject; LtDebugPrint (3, ("[LpxTdi] LpxOpenConnection: returning\n")); return status; }
// // Plug in a device on LanscsiBus in KernelMode. // NTSTATUS LSBus_PlugInLSBUSDevice( PFDO_DEVICE_DATA FdoData, ULONG SlotNo, PWCHAR HardwareIDs, LONG HardwareIDLen, ULONG MaxBlocksPerRequest ){ PBUSENUM_PLUGIN_HARDWARE_EX BusDevice; ULONG Length; HANDLE DisconEvent; HANDLE AlarmEvent; NTSTATUS status; // // Create events // status = ZwCreateEvent( &DisconEvent, GENERIC_READ, NULL, NotificationEvent, FALSE ); if(!NT_SUCCESS(status)) { Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PlugInLSBUSDevice: ZwCreateEvent() failed. Disconnection event.\n")); return status; } status = ZwCreateEvent( &AlarmEvent, GENERIC_READ, NULL, NotificationEvent, FALSE ); if(!NT_SUCCESS(status)) { ZwClose(DisconEvent); Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PlugInLSBUSDevice: ExAllocatePoolWithTag() failed. AlarmEvent\n")); return status; } // // Build BUSENUM_PLUGIN_HARDWARE_EX structure. // Length = sizeof(BUSENUM_PLUGIN_HARDWARE_EX) + HardwareIDLen; BusDevice = ExAllocatePoolWithTag( PagedPool, Length, LSBUS_POOTAG_PLUGIN ); if(!BusDevice) { ZwClose(DisconEvent); ZwClose(AlarmEvent); Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PlugInLSBUSDevice: ExAllocatePoolWithTag() failed.\n")); return STATUS_INSUFFICIENT_RESOURCES; } BusDevice->Size = Length; BusDevice->SlotNo = SlotNo; RtlCopyMemory(BusDevice->HardwareIDs, HardwareIDs, HardwareIDLen); BusDevice->MaxRequestBlocks = MaxBlocksPerRequest; BusDevice->phAlarmEvent = &AlarmEvent; BusDevice->phEvent = &DisconEvent; status = Bus_PlugInDeviceEx(BusDevice, Length, FdoData, KernelMode); // // Close handle to decrease one reference from events. // ZwClose(AlarmEvent); ZwClose(DisconEvent); ExFreePool(BusDevice); return status; }
NTSTATUS LpxTdiOpenAddress( OUT PHANDLE AddressFileHandle, OUT PFILE_OBJECT *AddressFileObject, IN PTDI_ADDRESS_LPX Address ) { HANDLE addressFileHandle; PFILE_OBJECT addressFileObject; UNICODE_STRING nameString; OBJECT_ATTRIBUTES objectAttributes; UCHAR eaFullBuffer[ADDRESS_EA_BUFFER_LENGTH]; PFILE_FULL_EA_INFORMATION eaBuffer = (PFILE_FULL_EA_INFORMATION)eaFullBuffer; PTRANSPORT_ADDRESS transportAddress; PTA_ADDRESS taAddress; PTDI_ADDRESS_LPX lpxAddress; INT i; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; LtDebugPrint (3, ("[LpxTdi] TdiOpenAddress: Entered\n")); // // Init object attributes // RtlInitUnicodeString (&nameString, TRANSPORT_NAME); InitializeObjectAttributes ( &objectAttributes, &nameString, 0, NULL, NULL ); RtlZeroMemory(eaBuffer, ADDRESS_EA_BUFFER_LENGTH); eaBuffer->NextEntryOffset = 0; eaBuffer->Flags = 0; eaBuffer->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH; eaBuffer->EaValueLength = FIELD_OFFSET(TRANSPORT_ADDRESS, Address) + FIELD_OFFSET(TA_ADDRESS, Address) + TDI_ADDRESS_LENGTH_LPX; for (i=0;i<(int)eaBuffer->EaNameLength;i++) { eaBuffer->EaName[i] = TdiTransportAddress[i]; } transportAddress = (PTRANSPORT_ADDRESS)&eaBuffer->EaName[eaBuffer->EaNameLength+1]; transportAddress->TAAddressCount = 1; taAddress = (PTA_ADDRESS)transportAddress->Address; taAddress->AddressType = TDI_ADDRESS_TYPE_LPX; taAddress->AddressLength = TDI_ADDRESS_LENGTH_LPX; lpxAddress = (PTDI_ADDRESS_LPX)taAddress->Address; RtlCopyMemory( lpxAddress, Address, sizeof(TDI_ADDRESS_LPX) ); // // Open Address File // status = ZwCreateFile( &addressFileHandle, GENERIC_READ, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, 0, 0, eaBuffer, ADDRESS_EA_BUFFER_LENGTH ); if (!NT_SUCCESS(status)) { LtDebugPrint (0,("[LpxTdi] TdiOpenAddress: FAILURE, NtCreateFile returned status code=%x.\n", status)); *AddressFileHandle = NULL; *AddressFileObject = NULL; return status; } status = ioStatusBlock.Status; if (!NT_SUCCESS(status)) { LtDebugPrint (0, ("[LpxTdi] TdiOpenAddress: FAILURE, IoStatusBlock.Status contains status code=%x\n", status)); *AddressFileHandle = NULL; *AddressFileObject = NULL; return status; } status = ObReferenceObjectByHandle ( addressFileHandle, 0L, NULL, KernelMode, (PVOID *) &addressFileObject, NULL ); if (!NT_SUCCESS(status)) { LtDebugPrint(0,("[LpxTdi] TdiOpenAddress: ObReferenceObjectByHandle() failed. STATUS=%08lx\n", status)); ZwClose(addressFileHandle); *AddressFileHandle = NULL; *AddressFileObject = NULL; return status; } *AddressFileHandle = addressFileHandle; *AddressFileObject = addressFileObject; LtDebugPrint (3, ("[LpxTdi] TdiOpenAddress: returning\n")); return status; }
VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegCloseKey(IN HANDLE hKey) { return ZwClose(hKey); }
/** * 检测文件大小并做后处理,如果文件超过规定大小重新创建文件:2个参数 * 根据需要进行重建方针的选择,在日志系统初始化时一般采用1或2,当写入日志文件中判断大小采用1. */ NTSTATUS CheckLogFileSizeAndReCreateLogFile(PUNICODE_STRING pRecreateFilename,USHORT strategy,HANDLE& logFile) { OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK ioStatus; //获取文件大小 FILE_STANDARD_INFORMATION fsi; NTSTATUS ntStatus = ::ZwQueryInformationFile(logFile,&ioStatus,&fsi,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation); if(!NT_SUCCESS(ntStatus) ) { KdPrint( ("Strategy:%d:Get file's length error!\n",g_logStrategy) ); return ntStatus; } if(fsi.EndOfFile.QuadPart >= g_logFileMaxSize)//文件超过大小,关闭该文件,重建 { ZwClose(logFile); InitializeObjectAttributes(&objectAttributes,pRecreateFilename,OBJ_CASE_INSENSITIVE,NULL, NULL); if(strategy == 1) { KdPrint( ("Recreate File\n") ); ntStatus = ZwCreateFile(&logFile,FILE_READ_ATTRIBUTES | FILE_APPEND_DATA | SYNCHRONIZE, &objectAttributes,&ioStatus,NULL,FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_SUPERSEDE,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0); if(!NT_SUCCESS(ntStatus)) { //对于策略1无影响,如果为策略2,g_logCurrentFileNumber返回改为原有值 g_logCurrentFileNumber = (g_logCurrentFileNumber > 0) ? 0 : 1; KdPrint( ("Strategy:%d:ReCreate File Error!\n",g_logStrategy)); return ntStatus; } WCHAR uhead = 0xFEFF; ntStatus = ZwWriteFile(logFile,NULL,NULL,NULL,&ioStatus,&uhead,sizeof(WCHAR),NULL,NULL);//写入表明Unicode文件标识号的字头 //ZwClose(logFile); } else { KdPrint( ("Open Another File\n") ); ntStatus = ZwCreateFile(&g_logFile,FILE_READ_ATTRIBUTES | FILE_APPEND_DATA | SYNCHRONIZE, &objectAttributes,&ioStatus,NULL,FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0); if(!NT_SUCCESS(ntStatus)) { //对于策略1无影响,如果为策略2,g_logCurrentFileNumber返回改为原有值 g_logCurrentFileNumber = (g_logCurrentFileNumber > 0) ? 0 : 1; KdPrint( ("Strategy:%d:ReCreate File Error!\n",g_logStrategy)); return ntStatus; } } } else g_logCurrentFileNumber = (g_logCurrentFileNumber > 0) ? 0 : 1;//对于策略1无影响,如果为策略2,g_logCurrentFileNumber返回改为原有值 return STATUS_SUCCESS; }
// // Initializes the NRER subsystem by creating a file-backed section that is // pointed at the NRER user-mode DLL on disk. This section is used for // randomization purposes. // NTSTATUS InitializeNreSubsystem() { OBJECT_ATTRIBUTES Attributes; IO_STATUS_BLOCK IoStatus; UNICODE_STRING FilePath; NTSTATUS Status = STATUS_SUCCESS; HANDLE FileHandle; HANDLE SectionHandle; do { // // Get a file handle to the user-mode DLL // RtlInitUnicodeString( &FilePath, NRER_USER_MODE_DLL_PATH); InitializeObjectAttributes( &Attributes, &FilePath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); if (!NT_SUCCESS(Status = ZwOpenFile( &FileHandle, GENERIC_READ | GENERIC_EXECUTE, &Attributes, &IoStatus, FILE_SHARE_READ | FILE_SHARE_WRITE, 0))) { DebugPrint(("InitializeNreSubsystem(): ZwCreateFile(%wZ) failed, %.8x.", &FilePath, Status)); break; } // // Create an image file-backed section that is associated with the DLL // if (!NT_SUCCESS(Status = ZwCreateSection( &SectionHandle, SECTION_ALL_ACCESS, NULL, NULL, PAGE_EXECUTE_WRITECOPY, SEC_IMAGE, FileHandle))) { DebugPrint(("InitializeNreSubsystem(): ZwCreateSection() failed, %.8x.", Status)); break; } // // Get the section object that's associated with the section handle // if (!NT_SUCCESS(Status = ObReferenceObjectByHandle( SectionHandle, 0, NULL, KernelMode, (PVOID *)&NrerUserModeDllSectionObject, NULL))) { DebugPrint(("InitializeNreSubsystem(): ObReferenceObjectByHandle() failed, %.8x.", Status)); break; } DebugPrint(("InitializeNreSubsystem(): NRER user-mode DLL section at: %p.", NrerUserModeDllSectionObject)); NrerInitialized = TRUE; } while (0); // // Close the handles that were opened // if (FileHandle) ZwClose( FileHandle); if (SectionHandle) ZwClose( SectionHandle); return Status; }
// get ptr to an EPROCESS struct from the name (i.m.weasel) NTSTATUS GetEProcessByName(WCHAR *processname, PEPROCESS *proc) { NTSTATUS status; PSYSTEM_PROCESS_INFORMATION info, curr; ULONG info_size = PAGE_SIZE, result_size; ULONG ProcessId = 0; CLIENT_ID ClientId; OBJECT_ATTRIBUTES ObjectAttributes; PVOID Object; ULONG length; HANDLE Services_process; *proc = NULL; while(TRUE) { info = ExAllocatePool (NonPagedPool, info_size); if (info == NULL) return STATUS_NO_MEMORY; status = ZwQuerySystemInformation ( 5, // process request info, info_size, &result_size); if( NT_SUCCESS(status) ) break; ExFreePool(info); if( status != STATUS_INFO_LENGTH_MISMATCH ) return STATUS_NO_MEMORY; // otherwise, we need to allocate more memory info = NULL; info_size += PAGE_SIZE; } length = wcslen(processname); curr = info; do { if((curr->ProcessName.Length == (length * sizeof (WCHAR))) && !memcmp(processname, curr->ProcessName.Buffer, curr->ProcessName.Length)) { // it's our services.exe ProcessId = curr->ProcessId; break; } if(curr->NextEntryDelta) (PBYTE)curr += (curr->NextEntryDelta); } while(curr->NextEntryDelta); ExFreePool(info); if (!ProcessId) return STATUS_NOT_FOUND; InitializeObjectAttributes( &ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0); ClientId.UniqueProcess = (HANDLE)ProcessId; ClientId.UniqueThread = 0; status = ZwOpenProcess( &Services_process, PROCESS_ALL_ACCESS, &ObjectAttributes, &ClientId); if ( !NT_SUCCESS(status) ) return status; status = ObReferenceObjectByHandle ( Services_process, PROCESS_ALL_ACCESS, NULL, KernelMode, &Object, NULL); ZwClose (Services_process); if (!NT_SUCCESS(status)) return status; *proc = (PEPROCESS)Object; return STATUS_SUCCESS; }
BOOL WINAPI _AvpSetFileAttributes( LPCTSTR lpFileName, // address of filename DWORD dwFileAttributes // address of attributes to set ) { NTSTATUS ntStatus; HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatus; UNICODE_STRING uniFilename; ANSI_STRING ansiFilename; BOOL ret=FALSE; int n=InternalAccessAdd(lpFileName); RtlInitAnsiString( &ansiFilename, lpFileName ); RtlAnsiStringToUnicodeString( &uniFilename, &ansiFilename, TRUE); InitializeObjectAttributes( &ObjectAttributes, &uniFilename, OBJ_CASE_INSENSITIVE, NULL, NULL ); ++InMyOpenClose; ntStatus = ZwCreateFile( &FileHandle, FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES|SYNCHRONIZE, &ObjectAttributes, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT|FILE_COMPLETE_IF_OPLOCKED, NULL, 0 ); --InMyOpenClose; RtlFreeUnicodeString( &uniFilename ); if ( ntStatus != STATUS_SUCCESS ) { if (ntStatus == STATUS_OPLOCK_BREAK_IN_PROGRESS) { ++InMyOpenClose; ZwClose( FileHandle ); --InMyOpenClose; } goto ret; } FILE_BASIC_INFORMATION BasicInfo; ntStatus = ZwQueryInformationFile( FileHandle, &IoStatus, &BasicInfo, sizeof( FILE_BASIC_INFORMATION ), FileBasicInformation ); if(ntStatus!=STATUS_SUCCESS){ ++InMyOpenClose; ZwClose( FileHandle ); --InMyOpenClose; goto ret; } BasicInfo.FileAttributes=dwFileAttributes; ntStatus = ZwSetInformationFile( FileHandle, &IoStatus, &BasicInfo, sizeof( FILE_BASIC_INFORMATION ), FileBasicInformation ); if(ntStatus!=STATUS_SUCCESS){ ++InMyOpenClose; ZwClose( FileHandle ); --InMyOpenClose; goto ret; } ++InMyOpenClose; ntStatus = ZwClose( FileHandle ); --InMyOpenClose; if ( ntStatus != STATUS_SUCCESS ) goto ret; ret=TRUE; ret: // _DebugTrace(TraceInfo,"SetAttrib OK: %08X\n", dwFileAttributes); InternalAccessRemoveAt(n); return ret; }