NTSTATUS NTAPI CmpInitializeHive(OUT PCMHIVE *RegistryHive, IN ULONG OperationType, IN ULONG HiveFlags, IN ULONG FileType, IN PVOID HiveData OPTIONAL, IN HANDLE Primary, IN HANDLE Log, IN HANDLE External, IN PCUNICODE_STRING FileName OPTIONAL, IN ULONG CheckFlags) { PCMHIVE Hive; FILE_STANDARD_INFORMATION FileInformation; IO_STATUS_BLOCK IoStatusBlock; FILE_FS_SIZE_INFORMATION FileSizeInformation; NTSTATUS Status; ULONG Cluster; /* Assume failure */ *RegistryHive = NULL; /* * The following are invalid: * An external hive that is also internal. * A log hive that's not a primary hive too. * A volatile hive that's linked to permanent storage. * An in-memory initialization without hive data. * A log hive that's not linked to a correct file type. */ if (((External) && ((Primary) || (Log))) || ((Log) && !(Primary)) || ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) || ((OperationType == HINIT_MEMORY) && (!HiveData)) || ((Log) && (FileType != HFILE_TYPE_LOG))) { /* Fail the request */ return STATUS_INVALID_PARAMETER; } /* Check if this is a primary hive */ if (Primary) { /* Get the cluster size */ Status = ZwQueryVolumeInformationFile(Primary, &IoStatusBlock, &FileSizeInformation, sizeof(FILE_FS_SIZE_INFORMATION), FileFsSizeInformation); if (!NT_SUCCESS(Status)) return Status; /* Make sure it's not larger then the block size */ if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE) { /* Fail */ return STATUS_REGISTRY_IO_FAILED; } /* Otherwise, calculate the cluster */ Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE; Cluster = max(1, Cluster); } else { /* Otherwise use cluster 1 */ Cluster = 1; } /* Allocate the hive */ Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(CMHIVE), TAG_CM); if (!Hive) return STATUS_INSUFFICIENT_RESOURCES; /* Setup null fields */ Hive->UnloadEvent = NULL; Hive->RootKcb = NULL; Hive->Frozen = FALSE; Hive->UnloadWorkItem = NULL; Hive->GrowOnlyMode = FALSE; Hive->GrowOffset = 0; Hive->CellRemapArray = NULL; Hive->UseCountLog.Next = 0; Hive->LockHiveLog.Next = 0; Hive->FileObject = NULL; Hive->NotifyList.Flink = NULL; Hive->NotifyList.Blink = NULL; /* Set loading flag */ Hive->HiveIsLoading = TRUE; /* Set the current thread as creator */ Hive->CreatorOwner = KeGetCurrentThread(); /* Initialize lists */ InitializeListHead(&Hive->KcbConvertListHead); InitializeListHead(&Hive->KnodeConvertListHead); InitializeListHead(&Hive->TrustClassEntry); /* Allocate the view log */ Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool, sizeof(KGUARDED_MUTEX), TAG_CM); if (!Hive->ViewLock) { /* Cleanup allocation and fail */ ExFreePoolWithTag(Hive, TAG_CM); return STATUS_INSUFFICIENT_RESOURCES; } /* Allocate the flush lock */ Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERESOURCE), TAG_CM); if (!Hive->FlusherLock) { /* Cleanup allocations and fail */ ExFreePoolWithTag(Hive->ViewLock, TAG_CM); ExFreePoolWithTag(Hive, TAG_CM); return STATUS_INSUFFICIENT_RESOURCES; } /* Setup the handles */ Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary; Hive->FileHandles[HFILE_TYPE_LOG] = Log; Hive->FileHandles[HFILE_TYPE_EXTERNAL] = External; /* Initailize the guarded mutex */ KeInitializeGuardedMutex(Hive->ViewLock); Hive->ViewLockOwner = NULL; /* Initialize the flush lock */ ExInitializeResourceLite(Hive->FlusherLock); /* Setup hive locks */ ExInitializePushLock(&Hive->HiveLock); Hive->HiveLockOwner = NULL; ExInitializePushLock(&Hive->WriterLock); Hive->WriterLockOwner = NULL; ExInitializePushLock(&Hive->SecurityLock); Hive->HiveSecurityLockOwner = NULL; /* Clear file names */ RtlInitEmptyUnicodeString(&Hive->FileUserName, NULL, 0); RtlInitEmptyUnicodeString(&Hive->FileFullPath, NULL, 0); /* Initialize the view list */ CmpInitHiveViewList(Hive); /* Initailize the security cache */ CmpInitSecurityCache(Hive); /* Setup flags */ Hive->Flags = 0; Hive->FlushCount = 0; /* Set flags */ Hive->Flags = HiveFlags; /* Check if this is a primary */ if (Primary) { /* Check how large the file is */ ZwQueryInformationFile(Primary, &IoStatusBlock, &FileInformation, sizeof(FileInformation), FileStandardInformation); Cluster = FileInformation.EndOfFile.LowPart; } /* Initialize it */ Status = HvInitialize(&Hive->Hive, OperationType, FileType, HiveFlags, HiveData, CmpAllocate, CmpFree, CmpFileSetSize, CmpFileWrite, CmpFileRead, CmpFileFlush, Cluster, FileName); if (!NT_SUCCESS(Status)) { /* Cleanup allocations and fail */ ExDeleteResourceLite(Hive->FlusherLock); ExFreePoolWithTag(Hive->FlusherLock, TAG_CM); ExFreePoolWithTag(Hive->ViewLock, TAG_CM); ExFreePoolWithTag(Hive, TAG_CM); return Status; } /* Check if we should verify the registry */ if ((OperationType == HINIT_FILE) || (OperationType == HINIT_MEMORY) || (OperationType == HINIT_MEMORY_INPLACE) || (OperationType == HINIT_MAPFILE)) { /* Verify integrity */ ULONG CheckStatus = CmCheckRegistry(Hive, CheckFlags); if (CheckStatus != 0) { /* Cleanup allocations and fail */ ExDeleteResourceLite(Hive->FlusherLock); ExFreePoolWithTag(Hive->FlusherLock, TAG_CM); ExFreePoolWithTag(Hive->ViewLock, TAG_CM); ExFreePoolWithTag(Hive, TAG_CM); return STATUS_REGISTRY_CORRUPT; } } /* Lock the hive list */ ExAcquirePushLockExclusive(&CmpHiveListHeadLock); /* Insert this hive */ InsertHeadList(&CmpHiveListHead, &Hive->HiveList); /* Release the lock */ ExReleasePushLock(&CmpHiveListHeadLock); /* Return the hive and success */ *RegistryHive = (PCMHIVE)Hive; return STATUS_SUCCESS; }
NTSTATUS NTAPI SeInitializeProcessAuditName(IN PFILE_OBJECT FileObject, IN BOOLEAN DoAudit, OUT POBJECT_NAME_INFORMATION *AuditInfo) { OBJECT_NAME_INFORMATION LocalNameInfo; POBJECT_NAME_INFORMATION ObjectNameInfo = NULL; ULONG ReturnLength = 8; NTSTATUS Status; PAGED_CODE(); ASSERT(AuditInfo); /* Check if we should do auditing */ if (DoAudit) { /* FIXME: TODO */ } /* Now query the name */ Status = ObQueryNameString(FileObject, &LocalNameInfo, sizeof(LocalNameInfo), &ReturnLength); if (((Status == STATUS_BUFFER_OVERFLOW) || (Status == STATUS_BUFFER_TOO_SMALL) || (Status == STATUS_INFO_LENGTH_MISMATCH)) && (ReturnLength != sizeof(LocalNameInfo))) { /* Allocate required size */ ObjectNameInfo = ExAllocatePoolWithTag(NonPagedPool, ReturnLength, TAG_SEPA); if (ObjectNameInfo) { /* Query the name again */ Status = ObQueryNameString(FileObject, ObjectNameInfo, ReturnLength, &ReturnLength); } } /* Check if we got here due to failure */ if ((ObjectNameInfo) && (!(NT_SUCCESS(Status)) || (ReturnLength == sizeof(LocalNameInfo)))) { /* First, free any buffer we might've allocated */ ASSERT(FALSE); if (ObjectNameInfo) ExFreePool(ObjectNameInfo); /* Now allocate a temporary one */ ReturnLength = sizeof(OBJECT_NAME_INFORMATION); ObjectNameInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(OBJECT_NAME_INFORMATION), TAG_SEPA); if (ObjectNameInfo) { /* Clear it */ RtlZeroMemory(ObjectNameInfo, ReturnLength); Status = STATUS_SUCCESS; } } /* Check if memory allocation failed */ if (!ObjectNameInfo) Status = STATUS_NO_MEMORY; /* Return the audit name */ *AuditInfo = ObjectNameInfo; /* Return status */ return Status; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Generates a message using "pid", "message" and "parameter" and sends it back to userland throught // a filter communication port. // Parameters : // _in_opt_ ULONG pid : Process ID from which the logs are produced. // _in_opt_ PWCHAR message : Message (function name most of the time). // _in_opt_ PWCHAR parameter : Function args. // Return value : // NTSTATUS : FltSendMessage return value. // Process : // - Retrieves the process name from the pid and saves the whole data into an ANSI string. // - Generates an ANSI string with the message, with the process name, pid, and function name, and the // - generic "parameter" parameter. The resulting output will basically follow this scheme: // "pid","proces_name","function_name","FAILED/SUCCESS(0/1)","return_value","number_of_arguments","argument1->value","argument2->value"... // - Uses the "mutex" mutex to avoid concurrency when using the FltSendMessage() function. ////////////////////////////////////////////////////////////////////////////////////////////////////////////// NTSTATUS sendLogs(ULONG pid, PWCHAR message, PWCHAR parameter) { NTSTATUS status = STATUS_SUCCESS; CHAR buf[MAXSIZE]; UNICODE_STRING processName; ULONG sizeBuf; LARGE_INTEGER timeout; timeout.QuadPart = -((LONGLONG)0.5*10*1000*1000); if(message == NULL) return STATUS_INVALID_PARAMETER; #ifdef DEBUG DbgPrint("SendLogs\n"); #endif processName.Length = 0; processName.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR); processName.Buffer = ExAllocatePoolWithTag(NonPagedPool, processName.MaximumLength, PROCNAME_TAG); if(!processName.Buffer) { KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, &timeout); KeReleaseMutex(&mutex, FALSE); return STATUS_NO_MEMORY; } status = getProcNameByPID(pid, &processName); if(!NT_SUCCESS(status)) { KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, &timeout); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); return status; } status = RtlStringCbPrintfA(buf, MAXSIZE, "%d,%wZ,%ws,%ws\n", pid, &processName, message, parameter); if(!NT_SUCCESS(status) || status == STATUS_BUFFER_OVERFLOW) { KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, &timeout); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); return status; } status = RtlStringCbLengthA(buf, MAXSIZE, &sizeBuf); if(!NT_SUCCESS(status)) { KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, &timeout); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); return status; } KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); #ifdef DEBUG DbgPrint("\tmsg : %s\n", buf); #endif status = FltSendMessage(filter, &clientPort, buf, sizeBuf, NULL, 0, NULL); if(status == STATUS_TIMEOUT) DbgPrint("STATUS_TIMEOUT !!\n"); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); #ifdef DEBUG if(!NT_SUCCESS(status)) DbgPrint("return : 0x%08x\n", status); #endif DEBUG return status; }
NTSTATUS NTAPI PciInitializeArbiters(IN PPCI_FDO_EXTENSION FdoExtension) { PPCI_INTERFACE CurrentInterface, *Interfaces; PPCI_PDO_EXTENSION PdoExtension; PPCI_ARBITER_INSTANCE ArbiterInterface; NTSTATUS Status; PCI_SIGNATURE ArbiterType; ASSERT_FDO(FdoExtension); /* Loop all the arbiters */ for (ArbiterType = PciArb_Io; ArbiterType <= PciArb_BusNumber; ArbiterType++) { /* Check if this is the extension for the Root PCI Bus */ if (!PCI_IS_ROOT_FDO(FdoExtension)) { /* Get the PDO extension */ PdoExtension = FdoExtension->PhysicalDeviceObject->DeviceExtension; ASSERT_PDO(PdoExtension); /* Skip this bus if it does subtractive decode */ if (PdoExtension->Dependent.type1.SubtractiveDecode) { DPRINT1("PCI Not creating arbiters for subtractive bus %u\n", PdoExtension->Dependent.type1.SubtractiveDecode); continue; } } /* Query all the registered arbiter interfaces */ Interfaces = PciInterfaces; while (*Interfaces) { /* Find the one that matches the arbiter currently being setup */ CurrentInterface = *Interfaces; if (CurrentInterface->Signature == ArbiterType) break; Interfaces++; } /* Check if the required arbiter was not found in the list */ if (!*Interfaces) { /* Skip this arbiter and try the next one */ DPRINT1("PCI - FDO ext 0x%p no %s arbiter.\n", FdoExtension, PciArbiterNames[ArbiterType - PciArb_Io]); continue; } /* An arbiter was found, allocate an instance for it */ Status = STATUS_INSUFFICIENT_RESOURCES; ArbiterInterface = ExAllocatePoolWithTag(PagedPool, sizeof(PCI_ARBITER_INSTANCE), PCI_POOL_TAG); if (!ArbiterInterface) break; /* Setup the instance */ ArbiterInterface->BusFdoExtension = FdoExtension; ArbiterInterface->Interface = CurrentInterface; swprintf(ArbiterInterface->InstanceName, L"PCI %S (b=%02x)", PciArbiterNames[ArbiterType - PciArb_Io], FdoExtension->BaseBus); /* Call the interface initializer for it */ Status = CurrentInterface->Initializer(ArbiterInterface); if (!NT_SUCCESS(Status)) break; /* Link it with this FDO */ PcipLinkSecondaryExtension(&FdoExtension->SecondaryExtension, &FdoExtension->SecondaryExtLock, &ArbiterInterface->Header, ArbiterType, PciArbiterDestructor); /* This arbiter is now initialized, move to the next one */ DPRINT1("PCI - FDO ext 0x%p %S arbiter initialized (context 0x%p).\n", FdoExtension, L"ARBITER HEADER MISSING", //ArbiterInterface->CommonInstance.Name, ArbiterInterface); Status = STATUS_SUCCESS; } /* Return to caller */ return Status; }
BOOLEAN RememberRule(RULE_TYPE RuleType, PCHAR ObjectName, UCHAR OperationType) { PPOLICY_RULE rule = NewPolicy.RuleList[RuleType]; KIRQL irql; int len = 0; if (ObjectName) len = strlen(ObjectName); KeAcquireSpinLock(&NewPolicy.SpinLock, &irql); /* * don't save duplicate rules */ while (rule != NULL) { if ( (rule->MatchType == MATCH_ALL) || (rule->MatchType == MATCH_SINGLE && len == rule->NameLength && _stricmp(ObjectName, rule->Name) == 0) || (rule->MatchType == MATCH_WILDCARD && WildcardMatch(ObjectName, rule->Name) == WILDCARD_MATCH) ) { rule->OperationType |= OperationType; KeReleaseSpinLock(&NewPolicy.SpinLock, irql); return TRUE; } rule = (PPOLICY_RULE) rule->Next; } rule = ExAllocatePoolWithTag(NonPagedPool, sizeof(POLICY_RULE) + len, _POOL_TAG); if (rule == NULL) { LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("RememberRule: out of memory\n")); return FALSE; } RtlZeroMemory(rule, sizeof(POLICY_RULE)); rule->ActionType = ACTION_PERMIT; rule->OperationType = OperationType; if (ObjectName) { rule->NameLength = (USHORT) len; strcpy(rule->Name, ObjectName); rule->MatchType = MATCH_SINGLE; } else { rule->MatchType = MATCH_ALL; } rule->Next = NewPolicy.RuleList[RuleType]; NewPolicy.RuleList[RuleType] = rule; KeReleaseSpinLock(&NewPolicy.SpinLock, irql); return TRUE; }
NDIS_STATUS SxLibIssueOidRequest( _In_ PSX_SWITCH_OBJECT Switch, _In_ NDIS_REQUEST_TYPE RequestType, _In_ NDIS_OID Oid, _In_opt_ PVOID InformationBuffer, _In_ ULONG InformationBufferLength, _In_ ULONG OutputBufferLength, _In_ ULONG MethodId, _In_ UINT Timeout, _Out_ PULONG BytesNeeded ) { NDIS_STATUS status; PSX_OID_REQUEST oidRequest; PNDIS_OID_REQUEST ndisOidRequest; ULONG bytesNeeded; BOOLEAN asyncCompletion; status = NDIS_STATUS_SUCCESS; oidRequest = NULL; bytesNeeded = 0; asyncCompletion = FALSE; NdisInterlockedIncrement(&Switch->PendingOidCount); if (Switch->ControlFlowState != SxSwitchAttached) { status = NDIS_STATUS_CLOSING; goto Cleanup; } // // Dynamically allocate filter request so that we can handle asynchronous // completion. // oidRequest = (PSX_OID_REQUEST)ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(SX_OID_REQUEST), SxExtAllocationTag); if (oidRequest == NULL) { goto Cleanup; } NdisZeroMemory(oidRequest, sizeof(SX_OID_REQUEST)); ndisOidRequest = &oidRequest->NdisOidRequest; NdisInitializeEvent(&oidRequest->ReqEvent); ndisOidRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST; ndisOidRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1; ndisOidRequest->Header.Size = sizeof(NDIS_OID_REQUEST); ndisOidRequest->RequestType = RequestType; ndisOidRequest->Timeout = Timeout; switch (RequestType) { case NdisRequestQueryInformation: ndisOidRequest->DATA.QUERY_INFORMATION.Oid = Oid; ndisOidRequest->DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer; ndisOidRequest->DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength; break; case NdisRequestSetInformation: ndisOidRequest->DATA.SET_INFORMATION.Oid = Oid; ndisOidRequest->DATA.SET_INFORMATION.InformationBuffer = InformationBuffer; ndisOidRequest->DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength; break; case NdisRequestMethod: ndisOidRequest->DATA.METHOD_INFORMATION.Oid = Oid; ndisOidRequest->DATA.METHOD_INFORMATION.MethodId = MethodId; ndisOidRequest->DATA.METHOD_INFORMATION.InformationBuffer = InformationBuffer; ndisOidRequest->DATA.METHOD_INFORMATION.InputBufferLength = InformationBufferLength; ndisOidRequest->DATA.METHOD_INFORMATION.OutputBufferLength = OutputBufferLength; break; default: NT_ASSERT(FALSE); break; } ndisOidRequest->RequestId = (PVOID)SxExtOidRequestId; status = NdisFOidRequest(Switch->NdisFilterHandle, ndisOidRequest); if (status == NDIS_STATUS_PENDING) { asyncCompletion = TRUE; NdisWaitEvent(&oidRequest->ReqEvent, 0); } else { SxpNdisCompleteInternalOidRequest(Switch, ndisOidRequest, status); } bytesNeeded = oidRequest->BytesNeeded; status = oidRequest->Status; Cleanup: if (BytesNeeded != NULL) { *BytesNeeded = bytesNeeded; } if (!asyncCompletion) { NdisInterlockedDecrement(&Switch->PendingOidCount); } if (oidRequest != NULL) { ExFreePoolWithTag(oidRequest, SxExtAllocationTag); } return status; }
PVOID NTAPI MiAllocateContiguousMemory(IN SIZE_T NumberOfBytes, IN PFN_NUMBER LowestAcceptablePfn, IN PFN_NUMBER HighestAcceptablePfn, IN PFN_NUMBER BoundaryPfn, IN MEMORY_CACHING_TYPE CacheType) { PVOID BaseAddress; PFN_NUMBER SizeInPages; MI_PFN_CACHE_ATTRIBUTE CacheAttribute; // // Verify count and cache type // ASSERT(NumberOfBytes != 0); ASSERT(CacheType <= MmWriteCombined); // // Compute size requested // SizeInPages = BYTES_TO_PAGES(NumberOfBytes); // // Convert the cache attribute and check for cached requests // CacheAttribute = MiPlatformCacheAttributes[FALSE][CacheType]; if (CacheAttribute == MiCached) { // // Because initial nonpaged pool is supposed to be contiguous, go ahead // and try making a nonpaged pool allocation first. // BaseAddress = ExAllocatePoolWithTag(NonPagedPoolCacheAligned, NumberOfBytes, 'mCmM'); if (BaseAddress) { // // Now make sure it's actually contiguous (if it came from expansion // it might not be). // if (MiCheckForContiguousMemory(BaseAddress, SizeInPages, SizeInPages, LowestAcceptablePfn, HighestAcceptablePfn, BoundaryPfn, CacheAttribute)) { // // Sweet, we're in business! // return BaseAddress; } // // No such luck // ExFreePoolWithTag(BaseAddress, 'mCmM'); } } // // According to MSDN, the system won't try anything else if you're higher // than APC level. // if (KeGetCurrentIrql() > APC_LEVEL) return NULL; // // Otherwise, we'll go try to find some // return MiFindContiguousMemory(LowestAcceptablePfn, HighestAcceptablePfn, BoundaryPfn, SizeInPages, CacheType); }
NTSTATUS LspLogin( PLANSCSI_SESSION LSS, PLSSLOGIN_INFO LoginInfo, LSPROTO_TYPE LSProto, BOOLEAN LockCleanup ) { NTSTATUS status; ASSERT(LSS); ASSERT(LoginInfo); if(LSS->LanscsiProtocol) { return STATUS_INVALID_PARAMETER; } if(LSProto < 0 || LSProto >= LsprotoCnt ) { return STATUS_INVALID_PARAMETER; } LSS->LanscsiProtocol = LsprotoList[LSProto]; if(!LSS->LanscsiProtocol->LsprotoFunc.LsprotoLogin) { return STATUS_NOT_IMPLEMENTED; } // // initialize LanscsiSession // LSS->LoginType = LoginInfo->LoginType; RtlCopyMemory(&LSS->UserID, &LoginInfo->UserID, LSPROTO_USERID_LENGTH); RtlCopyMemory(&LSS->Password, &LoginInfo->Password, LSPROTO_PASSWORD_LENGTH); RtlCopyMemory((PVOID)LSS->Password_v2, (PVOID)LoginInfo->Password_v2, LSPROTO_PASSWORD_V2_LENGTH); LSS->MaxBlocksPerRequest = LoginInfo->MaxBlocksPerRequest; LSS->LanscsiTargetID = LoginInfo->LanscsiTargetID; LSS->LanscsiLU = LoginInfo->LanscsiLU; LSS->HWType = LoginInfo->HWType; LSS->HWVersion = LoginInfo->HWVersion; LSS->HWRevision = LoginInfo->HWRevision; LSS->BlockInBytes = LoginInfo->BlockInBytes; LSS->HWProtoType = HARDWARETYPE_TO_PROTOCOLTYPE(LoginInfo->HWType); LSS->HWProtoVersion = (BYTE)LSProto; LSS->HPID = 0; LSS->RPID = 0; LSS->CommandTag = 0; LSS->WriteSplitSize = 8; // Start with small value. LSS->MaxBlocks is not yet initialized. LSS->ReadSplitSize = 8; status = LSS->LanscsiProtocol->LsprotoFunc.LsprotoLogin( LSS, LoginInfo ); if(NT_SUCCESS(status)) { LONG lockMax; LONG lockIdx; LSS->WriteSplitSize = LSS->MaxBlocksPerRequest; // Start with max possible blocks. LSS->ReadSplitSize = LSS->MaxBlocksPerRequest; ASSERT(LSS->WriteSplitSize <=128); ASSERT(LSS->WriteSplitSize >0); if(LoginInfo->IsEncryptBuffer) { ULONG encBuffSize; encBuffSize = LSS->MaxBlocksPerRequest * LSS->BlockInBytes; KDPrintM(DBG_PROTO_TRACE, ("Allocating a encryption buffer. BufferSize:%lu\n", encBuffSize)); LSS->EncryptBuffer = ExAllocatePoolWithTag( NonPagedPool, encBuffSize, LSS_ENCRYPTBUFFER_POOLTAG); if(!LSS->EncryptBuffer) { LSS->EncryptBufferLength = 0; KDPrintM(DBG_PROTO_ERROR, ("Error! Could not allocate the encrypt buffer! Performace may slow down.\n")); } else { LSS->EncryptBufferLength = encBuffSize; } } LSS->WriteCheckBuffer = ExAllocatePoolWithTag( NonPagedPool, LSS->MaxBlocksPerRequest * LSS->BlockInBytes, LSS_WRITECHECK_BUFFER_POOLTAG); if(!LSS->WriteCheckBuffer) { KDPrintM(DBG_PROTO_ERROR, ("Error! Could not allocate the write-check buffer!\n")); } LSS->DigestPatchBuffer = ExAllocatePoolWithTag( NonPagedPool, LSS->MaxBlocksPerRequest * LSS->BlockInBytes + 16, LSS_DIGEST_PATCH_POOLTAG); if(!LSS->DigestPatchBuffer) { KDPrintM(DBG_PROTO_ERROR, ("Error! Could not allocate the digest patch buffer! Performace may slow down.\n")); } // // Clean up locks // if(LockCleanup) { if(LSS->HWProtoVersion >= LSIDEPROTO_VERSION_1_1) { lockMax = LANSCSIIDE_MAX_LOCK_VER11; } else { lockMax = 0; } KDPrintM(DBG_PROTO_TRACE, ("Clean up locks of %u\n", lockMax)); for(lockIdx = 0; lockIdx < lockMax; lockIdx ++) { LspAcquireLock(LSS, (UCHAR)lockIdx, NULL); LspReleaseLock(LSS, (UCHAR)lockIdx, NULL); } } } else { LSS->LanscsiProtocol = NULL; } return status; }
/** * Internal worker for the RTMpOn* APIs. * * @returns IPRT status code. * @param pfnWorker The callback. * @param pvUser1 User argument 1. * @param pvUser2 User argument 2. * @param enmCpuid What to do / is idCpu valid. * @param idCpu Used if enmCpuid RT_NT_CPUID_SPECIFIC, otherwise ignored. */ static int rtMpCall(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2, RT_NT_CPUID enmCpuid, RTCPUID idCpu) { PRTMPARGS pArgs; KDPC *paExecCpuDpcs; #if 0 /* KeFlushQueuedDpcs must be run at IRQL PASSIVE_LEVEL according to MSDN, but the * driver verifier doesn't complain... */ AssertMsg(KeGetCurrentIrql() == PASSIVE_LEVEL, ("%d != %d (PASSIVE_LEVEL)\n", KeGetCurrentIrql(), PASSIVE_LEVEL)); #endif #ifdef IPRT_TARGET_NT4 KAFFINITY Mask; /* g_pfnrtNt* are not present on NT anyway. */ return VERR_NOT_SUPPORTED; #else KAFFINITY Mask = KeQueryActiveProcessors(); #endif /* KeFlushQueuedDpcs is not present in Windows 2000; import it dynamically so we can just fail this call. */ if (!g_pfnrtNtKeFlushQueuedDpcs) return VERR_NOT_SUPPORTED; pArgs = (PRTMPARGS)ExAllocatePoolWithTag(NonPagedPool, MAXIMUM_PROCESSORS*sizeof(KDPC) + sizeof(RTMPARGS), (ULONG)'RTMp'); if (!pArgs) return VERR_NO_MEMORY; pArgs->pfnWorker = pfnWorker; pArgs->pvUser1 = pvUser1; pArgs->pvUser2 = pvUser2; pArgs->idCpu = NIL_RTCPUID; pArgs->cHits = 0; paExecCpuDpcs = (KDPC *)(pArgs + 1); if (enmCpuid == RT_NT_CPUID_SPECIFIC) { KeInitializeDpc(&paExecCpuDpcs[0], rtmpNtDPCWrapper, pArgs); KeSetImportanceDpc(&paExecCpuDpcs[0], HighImportance); KeSetTargetProcessorDpc(&paExecCpuDpcs[0], (int)idCpu); } else { for (unsigned i = 0; i < MAXIMUM_PROCESSORS; i++) { KeInitializeDpc(&paExecCpuDpcs[i], rtmpNtDPCWrapper, pArgs); KeSetImportanceDpc(&paExecCpuDpcs[i], HighImportance); KeSetTargetProcessorDpc(&paExecCpuDpcs[i], i); } } /* Raise the IRQL to DISPATCH_LEVEL so we can't be rescheduled to another cpu. * KeInsertQueueDpc must also be executed at IRQL >= DISPATCH_LEVEL. */ KIRQL oldIrql; KeRaiseIrql(DISPATCH_LEVEL, &oldIrql); /* * We cannot do other than assume a 1:1 relationship between the * affinity mask and the process despite the warnings in the docs. * If someone knows a better way to get this done, please let bird know. */ if (enmCpuid == RT_NT_CPUID_SPECIFIC) { BOOLEAN ret = KeInsertQueueDpc(&paExecCpuDpcs[0], 0, 0); Assert(ret); } else { unsigned iSelf = KeGetCurrentProcessorNumber(); for (unsigned i = 0; i < MAXIMUM_PROCESSORS; i++) { if ( (i != iSelf) && (Mask & RT_BIT_64(i))) { BOOLEAN ret = KeInsertQueueDpc(&paExecCpuDpcs[i], 0, 0); Assert(ret); } } if (enmCpuid != RT_NT_CPUID_OTHERS) pfnWorker(iSelf, pvUser1, pvUser2); } KeLowerIrql(oldIrql); /* Flush all DPCs and wait for completion. (can take long!) */ /** @todo Consider changing this to an active wait using some atomic inc/dec * stuff (and check for the current cpu above in the specific case). */ g_pfnrtNtKeFlushQueuedDpcs(); ExFreePool(pArgs); return VINF_SUCCESS; }
NTSTATUS StartDevice( PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated ) { USB_CONFIGURATION_DESCRIPTOR tcd; PUSB_CONFIGURATION_DESCRIPTOR pcd; PUSB_STRING_DESCRIPTOR desc; HANDLE RecoveryHandle; PURB selurb; URB urb; NTSTATUS status; status = STATUS_SUCCESS; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; selurb = NULL; pcd = NULL; // Read our device descriptor. The only real purpose to this would be to find out how many // configurations there are so we can read their descriptors. In this simplest of examples, // there's only one configuration. KdPrint((DRIVERNAME " - Start device\n")); UsbBuildGetDescriptorRequest( &urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_DEVICE_DESCRIPTOR_TYPE, 0, LangId, &pdx->dd, NULL, sizeof(pdx->dd), NULL ); status = SendAwaitUrb( fdo, &urb ); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to retrieve device descriptor\n", status)); goto cleanup; } // allocate the buffer for the descriptor; take extra space to null terminate the bString member desc = (PUSB_STRING_DESCRIPTOR)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, SPOT_TAG ); if(!desc) { KdPrint((DRIVERNAME " - Unable to allocate %X bytes for string descriptor\n", sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes)); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } pdx->devHash = desc; UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, DeviceId, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to retrieve string descriptor for DeviceId\n", status)); goto cleanup; } // null terminate the buffer; we allocated one more wchar_t for the purpose desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; UpdateDeviceInformation( fdo ); // Read the descriptor of the first configuration. This requires two steps. The first step // reads the fixed-size configuration descriptor alone. The second step reads the // configuration descriptor plus all imbedded interface and endpoint descriptors. UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, LangId, &tcd, NULL, sizeof(tcd), NULL); status = SendAwaitUrb(fdo, &urb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status)); goto cleanup; } ULONG size = tcd.wTotalLength; pcd = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePoolWithTag(NonPagedPool, size, SPOT_TAG); if(!pcd) { KdPrint((DRIVERNAME " - Unable to allocate %X bytes for configuration descriptor\n", size)); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, LangId, pcd, NULL, size, NULL); status = SendAwaitUrb(fdo, &urb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status)); goto cleanup; } // Locate the descriptor for the one and only interface we expect to find PUSB_INTERFACE_DESCRIPTOR pid = USBD_ParseConfigurationDescriptorEx(pcd, pcd, -1, -1, -1, -1, -1); ASSERT(pid); // Create a URB to use in selecting a configuration. USBD_INTERFACE_LIST_ENTRY interfaces[2] = { {pid, NULL}, {NULL, NULL}, // fence to terminate the array }; selurb = USBD_CreateConfigurationRequestEx(pcd, interfaces); if(!selurb) { KdPrint((DRIVERNAME " - Unable to create configuration request\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } // Verify that the interface describes exactly the endpoints we expect if(pid->bNumEndpoints != 2) { KdPrint((DRIVERNAME " - %d is the wrong number of endpoints\n", pid->bNumEndpoints)); status = STATUS_DEVICE_CONFIGURATION_ERROR; goto cleanup; } PUSB_ENDPOINT_DESCRIPTOR ped = (PUSB_ENDPOINT_DESCRIPTOR) pid; ped = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(pcd, tcd.wTotalLength, ped, USB_ENDPOINT_DESCRIPTOR_TYPE); if(!ped || 0 == (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64) { KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n")); status = STATUS_DEVICE_CONFIGURATION_ERROR; goto cleanup; } ++ped; if(!ped || 0 != (ped->bEndpointAddress & 0x80) || ped->bmAttributes != USB_ENDPOINT_TYPE_BULK || ped->wMaxPacketSize > 64) { KdPrint((DRIVERNAME " - Endpoint has wrong attributes\n")); status = STATUS_DEVICE_CONFIGURATION_ERROR; goto cleanup; } ++ped; PUSBD_INTERFACE_INFORMATION pii = interfaces[0].Interface; ASSERT(pii->NumberOfPipes == pid->bNumEndpoints); // Initialize the maximum transfer size for each of the endpoints. The // default would be PAGE_SIZE. The firmware itself only has a 4096-byte // ring buffer, though. We need to restrict the test applet to that many // bytes. In order to exercise the multi-segment aspect of the transfer code, // therefore, reduce the maximum transfer size to 1024 bytes. pii->Pipes[0].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; pii->Pipes[1].MaximumTransferSize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; pdx->maxtransfer = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; // Submit the set-configuration request status = SendAwaitUrb(fdo, selurb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to select configuration\n", status)); goto cleanup; } // Save the configuration and pipe handles pdx->hconfig = selurb->UrbSelectConfiguration.ConfigurationHandle; pdx->hinpipe = pii->Pipes[0].PipeHandle; pdx->houtpipe = pii->Pipes[1].PipeHandle; // Transfer ownership of the configuration descriptor to the device extension pdx->pcd = pcd; pcd = NULL; // Enable the interface IoSetDeviceInterfaceState(&pdx->operationsInterfaceName, TRUE); // Enable the interface IoSetDeviceInterfaceState(&pdx->inquiriesInterfaceName, TRUE); // create recovery thread status = PsCreateSystemThread(&RecoveryHandle, 0, NULL, NULL, NULL, RecoveryThread, (PVOID)pdx); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - PsCreateSystemThread failed with error %08x\n", status)); goto cleanup; } status = ObReferenceObjectByHandle( RecoveryHandle, SYNCHRONIZE, NULL, KernelMode, (PVOID*)&pdx->RecoveryThread, NULL ); ASSERT(NT_SUCCESS(status)); ZwClose(RecoveryHandle); // Start polling status = StartPolling(pdx); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - StartPolling failed 0x%08x\n", status)); if(pdx->RecoveryThread) { // shutdown recovery thread pdx->RecoveryExit = TRUE; KeSetEvent(&pdx->RecoveryEvent, 0, FALSE); // wait for polling thread to exit KeWaitForSingleObject(pdx->RecoveryThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(pdx->RecoveryThread); pdx->RecoveryThread = NULL; } goto cleanup; } cleanup: if(selurb) ExFreePool(selurb); if(pcd ) ExFreePool(pcd ); // get rid of return codes like STATUS_PENDING if(NT_SUCCESS(status)) { return STATUS_SUCCESS; } return status; }
NTSTATUS LspCleanupLock( PLANSCSI_SESSION LSS, UCHAR LockNo ){ NTSTATUS status; LONG i; LANSCSI_PDUDESC pduDesc; BYTE pduResponse; PLANSCSI_SESSION tempLSS; LONG maxConn; LARGE_INTEGER GenericTimeOut; TA_LSTRANS_ADDRESS BindingAddress, TargetAddress; LSSLOGIN_INFO loginInfo; LSPROTO_TYPE LSProto; ULONG cleaned; // // Parameter check // if(LSS->HWProtoVersion <= LSIDEPROTO_VERSION_1_0) { return STATUS_NOT_SUPPORTED; } if(LSS->HWVersion >= 1) { maxConn = LANSCSIIDE_MAX_CONNECTION_VER11 - 1; } else { return STATUS_NOT_SUPPORTED; } tempLSS = ExAllocatePoolWithTag( NonPagedPool, maxConn * sizeof(LANSCSI_SESSION), LSS_POOLTAG); RtlZeroMemory(tempLSS, maxConn * sizeof(LANSCSI_SESSION)); // // Init variables // status = STATUS_SUCCESS; RtlZeroMemory(&pduDesc, sizeof(LANSCSI_PDUDESC)); pduDesc.Param8[3] = (UCHAR)LockNo; LspGetAddresses(LSS, &BindingAddress, &TargetAddress); GenericTimeOut.QuadPart = NANO100_PER_SEC * 5; cleaned = 0; // // Try to make connections to fill up connection pool of the NDAS device. // So, we can clear invalid acquisition of the locks. // KDPrintM(DBG_LURN_ERROR,("Try to clean up lock\n")); for (i=0 ; i < maxConn; i++) { // // Connect and log in with read-only access. // // connect LspSetTimeOut(&tempLSS[i], &GenericTimeOut); status = LspConnect( &tempLSS[i], &BindingAddress, &TargetAddress ); if(!NT_SUCCESS(status)) { KDPrintM(DBG_LURN_ERROR, ("LspConnect(), Can't Connect to the LS node. STATUS:0x%08x\n", status)); break; } } for (i=0; i < maxConn; i++) { if(!LspIsConnected(&tempLSS[i])) { continue; } KDPrintM(DBG_LURN_TRACE, ("Con#%u\n", i)); cleaned++; // extract login information from the existing LSS. LspBuildLoginInfo(LSS, &loginInfo); status = LspLookupProtocol(loginInfo.HWType, loginInfo.HWVersion, &LSProto); if(!NT_SUCCESS(status)) { LspDisconnect(&tempLSS[i]); KDPrintM(DBG_LURN_ERROR, ("Wrong hardware version.\n")); continue; } // Log in with read-only access. if (loginInfo.HWVersion == LANSCSIIDE_VERSION_2_5) { loginInfo.UserID = MAKE_USER_ID(DEFAULT_USER_NUM, USER_PERMISSION_RO); } else { loginInfo.UserID &= 0x0000ffff; } status = LspLogin( &tempLSS[i], &loginInfo, LSProto, FALSE ); if(!NT_SUCCESS(status)) { KDPrintM(DBG_LURN_ERROR, ("LspLogin() failed. STATUS:0x%08x\n", status)); LspDisconnect(&tempLSS[i]); ASSERT(FALSE); continue; } // // Acquire the lock on the NDAS device. // pduDesc.Command = VENDOR_OP_SET_MUTEX; status = LspVendorRequest( &tempLSS[i], &pduDesc, &pduResponse ); if(pduResponse != LANSCSI_RESPONSE_SUCCESS) { KDPrintM(DBG_LURN_ERROR, ("Acquiring lock #%u denied by NDAS device\n", LockNo)); } if(!NT_SUCCESS(status)) { LspDisconnect(&tempLSS[i]); KDPrintM(DBG_LURN_ERROR, ("LspVendorRequest() failed. STATUS=%08lx\n", status)); continue; } // // Release the lock on the NDAS device. // pduDesc.Command = VENDOR_OP_FREE_MUTEX; status = LspVendorRequest( &tempLSS[i], &pduDesc, &pduResponse ); if(pduResponse != LANSCSI_RESPONSE_SUCCESS) { KDPrintM(DBG_LURN_ERROR, ("Releasing lock #%u denied by NDAS device\n", LockNo)); } if(!NT_SUCCESS(status)) { LspDisconnect(&tempLSS[i]); KDPrintM(DBG_LURN_ERROR, ("LspVendorRequest() failed. STATUS=%08lx\n", status)); continue; } // // Log out and disconnect. // LspLogout( &tempLSS[i] ); LspDisconnect( &tempLSS[i] ); } KDPrintM(DBG_LURN_INFO, ("Cleaned #%u\n", cleaned)); ExFreePool(tempLSS); return status; }
NTSTATUS UpdateDeviceInformation( PDEVICE_OBJECT fdo ) { PUSB_STRING_DESCRIPTOR desc; UNICODE_STRING dummy; URB urb; int id; NTSTATUS status; KdPrint((DRIVERNAME " - UpdateDeviceInformation\n")); status = STATUS_SUCCESS; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; // initialize buffers pdx->manufacturer.Buffer = NULL; pdx->product .Buffer = NULL; pdx->serialNumber.Buffer = NULL; pdx->displayName .Buffer = NULL; desc = NULL; // allocate buffers for all strings pdx->manufacturer.Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG ); pdx->product .Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG ); pdx->serialNumber.Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG ); pdx->displayName .Buffer = (WCHAR*)ExAllocatePoolWithTag(NonPagedPool, StringDescriptorBytes, SPOT_TAG ); if( (pdx->manufacturer.Buffer == NULL) || (pdx->product .Buffer == NULL) || (pdx->serialNumber.Buffer == NULL) || (pdx->displayName .Buffer == NULL) ) { KdPrint((DRIVERNAME " - Unable to allocate memory for device info\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } pdx->manufacturer.Length = 0; pdx->manufacturer.MaximumLength = StringDescriptorBytes; pdx->product .Length = 0; pdx->product .MaximumLength = StringDescriptorBytes; pdx->serialNumber.Length = 0; pdx->serialNumber.MaximumLength = StringDescriptorBytes; pdx->displayName .Length = 0; pdx->displayName .MaximumLength = StringDescriptorBytes; // allocate buffer for device string descriptor requests desc = (PUSB_STRING_DESCRIPTOR)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, SPOT_TAG ); if(!desc) { KdPrint((DRIVERNAME " - Unable to allocate %X bytes for string descriptor\n", sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes)); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } if(0 != pdx->dd.iManufacturer) { // Manufacturer UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, pdx->dd.iManufacturer, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(NT_SUCCESS(status)) { desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; RtlInitUnicodeString( &dummy , desc->bString ); RtlCopyUnicodeString( &pdx->manufacturer, &dummy ); } else { RtlInitUnicodeString( &dummy , EmptyString ); RtlCopyUnicodeString( &pdx->manufacturer, &dummy ); KdPrint(( DRIVERNAME " - could not retrieve manufacturer %08x\n", status )); } } if(0 != pdx->dd.iProduct) { // Product UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, pdx->dd.iProduct, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(NT_SUCCESS(status)) { desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; RtlInitUnicodeString( &dummy , desc->bString ); RtlCopyUnicodeString( &pdx->product, &dummy ); } else { RtlInitUnicodeString( &dummy , EmptyString ); RtlCopyUnicodeString( &pdx->product, &dummy ); KdPrint(( DRIVERNAME " - could not retrieve product %08x\n", status )); } } if(0 != pdx->dd.iSerialNumber) { // Serial Number UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, pdx->dd.iSerialNumber, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(NT_SUCCESS(status)) { desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; RtlInitUnicodeString( &dummy , desc->bString ); RtlCopyUnicodeString( &pdx->serialNumber, &dummy ); } else { RtlInitUnicodeString( &dummy , EmptyString ); RtlCopyUnicodeString( &pdx->serialNumber, &dummy ); KdPrint(( DRIVERNAME " - could not retrieve serial number %08x\n", status )); } } // DisplayName UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE, DisplayNameId, LangId, desc, NULL, sizeof(USB_STRING_DESCRIPTOR) + StringDescriptorBytes, NULL); status = SendAwaitUrb(fdo, &urb); if(NT_SUCCESS(status)) { desc->bString[ (desc->bLength / 2) - 1 ] = L'\0'; RtlInitUnicodeString( &dummy , desc->bString ); RtlCopyUnicodeString( &pdx->displayName, &dummy ); } else { RtlInitUnicodeString( &dummy , EmptyString ); RtlCopyUnicodeString( &pdx->displayName, &dummy ); KdPrint(( DRIVERNAME " - could not retrieve display name %08x\n", status )); } cleanup: if(desc) ExFreePool( desc ); if(!NT_SUCCESS(status)) { if(pdx->manufacturer.Buffer) ExFreePool( pdx->manufacturer.Buffer ); if(pdx->product .Buffer) ExFreePool( pdx->product .Buffer ); if(pdx->serialNumber.Buffer) ExFreePool( pdx->serialNumber.Buffer ); if(pdx->displayName .Buffer) ExFreePool( pdx->displayName .Buffer ); pdx->manufacturer.Buffer = NULL; pdx->product .Buffer = NULL; pdx->serialNumber.Buffer = NULL; pdx->displayName .Buffer = NULL; } return status; }
VOID StartIo( PDEVICE_OBJECT fdo, PIRP Irp ) { PIO_STACK_LOCATION stack; PRWCONTEXT ctx; ULONG length, i; KIRQL OldIrql; NTSTATUS status; if((Irp == NULL) || (Irp->AssociatedIrp.SystemBuffer == NULL)) { CompleteRequest(Irp, STATUS_INVALID_PARAMETER, 0); return; } PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if(!NT_SUCCESS(status)) { CompleteRequest(Irp, status, 0); return; } stack = IoGetCurrentIrpStackLocation(Irp); if(stack->MajorFunction == IRP_MJ_WRITE) { // start a write operation ctx = (PRWCONTEXT) ExAllocatePoolWithTag(NonPagedPool, sizeof(RWCONTEXT), SPOT_TAG); if(ctx == NULL) { KdPrint((DRIVERNAME " - Could not allocate transfer context\n")); StartNextPacket ( &pdx->dqWrite, fdo ); CompleteRequest ( Irp, STATUS_INSUFFICIENT_RESOURCES, 0 ); IoReleaseRemoveLock( &pdx->RemoveLock, Irp ); return; } RtlZeroMemory(ctx, sizeof(RWCONTEXT)); ctx->total = ctx->remain = stack->Parameters.Write.Length; ctx->data = (PCHAR)Irp->AssociatedIrp.SystemBuffer; length = ctx->remain; if(length > pdx->maxtransfer) length = pdx->maxtransfer; UsbBuildInterruptOrBulkTransferRequest(&ctx->urb, sizeof(_URB_BULK_OR_INTERRUPT_TRANSFER), pdx->houtpipe, ctx->data, NULL, length, (USBD_TRANSFER_DIRECTION_OUT | USBD_SHORT_TRANSFER_OK), NULL); ctx->data += length; ctx->remain -= length; stack = IoGetNextIrpStackLocation(Irp); stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; stack->Parameters.Others.Argument1 = (PVOID)&ctx->urb; stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)OnWriteComplete, (PVOID) ctx, TRUE, TRUE, TRUE); IoCallDriver(pdx->LowerDeviceObject, Irp); } else { // flush KdPrint((DRIVERNAME " - Flushed!\n")); StartNextPacket ( &pdx->dqWrite, fdo ); CompleteRequest ( Irp, STATUS_SUCCESS, 0 ); IoReleaseRemoveLock( &pdx->RemoveLock, Irp ); } return; }
NTSTATUS NTAPI CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName, IN PCWSTR Extension OPTIONAL, OUT PHANDLE Primary, OUT PHANDLE Log, OUT PULONG PrimaryDisposition, OUT PULONG LogDisposition, IN BOOLEAN CreateAllowed, IN BOOLEAN MarkAsSystemHive, IN BOOLEAN NoBuffering, OUT PULONG ClusterSize OPTIONAL) { HANDLE EventHandle; PKEVENT Event; NTSTATUS Status; UNICODE_STRING FullName, ExtensionName; PWCHAR NameBuffer; USHORT Length; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; ULONG AttributeFlags, ShareMode, DesiredAccess, CreateDisposition, IoFlags; USHORT CompressionState; FILE_STANDARD_INFORMATION FileInformation; FILE_FS_SIZE_INFORMATION FsSizeInformation; /* Create event */ Status = CmpCreateEvent(NotificationEvent, &EventHandle, &Event); if (!NT_SUCCESS(Status)) return Status; /* Initialize the full name */ RtlInitEmptyUnicodeString(&FullName, NULL, 0); Length = BaseName->Length; /* Check if we have an extension */ if (Extension) { /* Update the name length */ Length += (USHORT)wcslen(Extension) * sizeof(WCHAR) + sizeof(UNICODE_NULL); /* Allocate the buffer for the full name */ NameBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_CM); if (!NameBuffer) { /* Fail */ ObDereferenceObject(Event); ZwClose(EventHandle); return STATUS_NO_MEMORY; } /* Build the full name */ FullName.Buffer = NameBuffer; FullName.MaximumLength = Length; RtlAppendUnicodeStringToString(&FullName, BaseName); } else { /* The base name is the full name */ FullName = *BaseName; NameBuffer = NULL; } /* Initialize the attributes */ InitializeObjectAttributes(&ObjectAttributes, &FullName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); /* Check if we can create the hive */ if ((CreateAllowed) && !(CmpShareSystemHives)) { /* Open only or create */ CreateDisposition = FILE_OPEN_IF; } else { /* Open only */ CreateDisposition = FILE_OPEN; } /* Setup the flags */ // FIXME : FILE_OPEN_FOR_BACKUP_INTENT is unimplemented and breaks 3rd stage boot IoFlags = //FILE_OPEN_FOR_BACKUP_INTENT | FILE_NO_COMPRESSION | FILE_RANDOM_ACCESS | (NoBuffering ? FILE_NO_INTERMEDIATE_BUFFERING : 0); /* Set share and access modes */ if ((CmpMiniNTBoot) && (CmpShareSystemHives)) { /* We're on Live CD or otherwise sharing */ DesiredAccess = FILE_READ_DATA; ShareMode = FILE_SHARE_READ; } else { /* We want to write exclusively */ ShareMode = 0; DesiredAccess = FILE_READ_DATA | FILE_WRITE_DATA; } /* Default attributes */ AttributeFlags = FILE_ATTRIBUTE_NORMAL; /* Now create the file */ Status = ZwCreateFile(Primary, DesiredAccess | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, AttributeFlags, ShareMode, CreateDisposition, FILE_SYNCHRONOUS_IO_NONALERT | IoFlags, NULL, 0); /* Check if anything failed until now */ if (!NT_SUCCESS(Status)) { /* Close handles and free buffers */ if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM); ObDereferenceObject(Event); ZwClose(EventHandle); DPRINT1("ZwCreateFile failed : %lx.\n", Status); *Primary = NULL; return Status; } if (MarkAsSystemHive) { /* We opened it, mark it as a system hive */ Status = ZwFsControlFile(*Primary, EventHandle, NULL, NULL, &IoStatusBlock, FSCTL_MARK_AS_SYSTEM_HIVE, NULL, 0, NULL, 0); if (Status == STATUS_PENDING) { /* Wait for completion */ KeWaitForSingleObject(Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } /* If we don't support it, ignore the failure */ if (Status == STATUS_INVALID_DEVICE_REQUEST) Status = STATUS_SUCCESS; if (!NT_SUCCESS(Status)) { /* Close handles and free buffers */ if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM); ObDereferenceObject(Event); ZwClose(EventHandle); ZwClose(*Primary); *Primary = NULL; return Status; } } /* Disable compression */ CompressionState = 0; Status = ZwFsControlFile(*Primary, EventHandle, NULL, NULL, &IoStatusBlock, FSCTL_SET_COMPRESSION, &CompressionState, sizeof(CompressionState), NULL, 0); if (Status == STATUS_PENDING) { /* Wait for completion */ KeWaitForSingleObject(Event, Executive, KernelMode, FALSE, NULL); } /* Get the disposition */ *PrimaryDisposition = (ULONG)IoStatusBlock.Information; if (IoStatusBlock.Information != FILE_CREATED) { /* Check how large the file is */ Status = ZwQueryInformationFile(*Primary, &IoStatusBlock, &FileInformation, sizeof(FileInformation), FileStandardInformation); if (NT_SUCCESS(Status)) { /* Check if it's 0 bytes */ if (!FileInformation.EndOfFile.QuadPart) { /* Assume it's a new file */ *PrimaryDisposition = FILE_CREATED; } } } /* Check if the caller wants cluster size returned */ if (ClusterSize) { /* Query it */ Status = ZwQueryVolumeInformationFile(*Primary, &IoStatusBlock, &FsSizeInformation, sizeof(FsSizeInformation), FileFsSizeInformation); if (!NT_SUCCESS(Status)) { /* Close handles and free buffers */ if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM); ObDereferenceObject(Event); ZwClose(EventHandle); return Status; } /* Check if the sector size is invalid */ if (FsSizeInformation.BytesPerSector > HBLOCK_SIZE) { /* Close handles and free buffers */ if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM); ObDereferenceObject(Event); ZwClose(EventHandle); return STATUS_CANNOT_LOAD_REGISTRY_FILE; } /* Return cluster size */ *ClusterSize = max(1, FsSizeInformation.BytesPerSector / HSECTOR_SIZE); } /* Check if we don't need to create a log file */ if (!Extension) { /* We're done, close handles */ ObDereferenceObject(Event); ZwClose(EventHandle); return STATUS_SUCCESS; } /* Check if we can create the hive */ CreateDisposition = CmpShareSystemHives ? FILE_OPEN : FILE_OPEN_IF; if (*PrimaryDisposition == FILE_CREATED) { /* Over-write the existing log file, since this is a new hive */ CreateDisposition = FILE_SUPERSEDE; } /* Setup the name */ RtlInitUnicodeString(&ExtensionName, Extension); RtlAppendUnicodeStringToString(&FullName, &ExtensionName); /* Initialize the attributes */ InitializeObjectAttributes(&ObjectAttributes, &FullName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); /* Setup the flags */ IoFlags = FILE_NO_COMPRESSION | FILE_NO_INTERMEDIATE_BUFFERING; /* Check if this is a log file */ if (!_wcsnicmp(Extension, L".log", 4)) { /* Hide log files */ AttributeFlags |= FILE_ATTRIBUTE_HIDDEN; } /* Now create the file */ Status = ZwCreateFile(Log, DesiredAccess, &ObjectAttributes, &IoStatusBlock, NULL, AttributeFlags, ShareMode, CreateDisposition, IoFlags, NULL, 0); if ((NT_SUCCESS(Status)) && (MarkAsSystemHive)) { /* We opened it, mark it as a system hive */ Status = ZwFsControlFile(*Log, EventHandle, NULL, NULL, &IoStatusBlock, FSCTL_MARK_AS_SYSTEM_HIVE, NULL, 0, NULL, 0); if (Status == STATUS_PENDING) { /* Wait for completion */ KeWaitForSingleObject(Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } /* If we don't support it, ignore the failure */ if (Status == STATUS_INVALID_DEVICE_REQUEST) Status = STATUS_SUCCESS; /* If we failed, close the handle */ if (!NT_SUCCESS(Status)) ZwClose(*Log); } /* Check if anything failed until now */ if (!NT_SUCCESS(Status)) { /* Clear the handle */ *Log = NULL; } else { /* Disable compression */ Status = ZwFsControlFile(*Log, EventHandle, NULL, NULL, &IoStatusBlock, FSCTL_SET_COMPRESSION, &CompressionState, sizeof(CompressionState), NULL, 0); if (Status == STATUS_PENDING) { /* Wait for completion */ KeWaitForSingleObject(Event, Executive, KernelMode, FALSE, NULL); } /* Return the disposition */ *LogDisposition = (ULONG)IoStatusBlock.Information; } /* We're done, close handles and free buffers */ if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM); ObDereferenceObject(Event); ZwClose(EventHandle); return STATUS_SUCCESS; }
NTSTATUS DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP IRP) { KdPrint(("==>DriverDeviceControl\n")); NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; ULONG tmpLen=0; PIO_STACK_LOCATION pIoStackIrp = IoGetCurrentIrpStackLocation(IRP); switch (pIoStackIrp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_SET_PROTECT_PID: KdPrint(("IOCTL_SET_PROTECT_PID\n")); { unsigned char pUnPack[256]; int unPackLength; unPackLength=DownloadUnPack((unsigned char *)IRP->AssociatedIrp.SystemBuffer,pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength,pUnPack); if (unPackLength>0) { PPID_INFO pInputBuffer = (PPID_INFO)pUnPack; int iStringLength = unPackLength; if(iStringLength != sizeof(PID_INFO)) // The PID should contain exactly 1 member. break; __int64 elapsedTime = __rdtsc() - pInputBuffer->currentTime; KdPrint(("IOCTL_SET_PROTECT_PID elapsed time: %I64d.\n", elapsedTime)); if((elapsedTime > COMMUNICATE_TIME_LIMIT)||(elapsedTime <=COMMUNICATE_TIME_DOWN)) { KdPrint(("IOCTL_SET_PROTECT_PID exceeds time limit.\n")); } else { // 加入进程 ID AddProtectPID(pInputBuffer->PID[0]); } ntStatus = STATUS_SUCCESS; } } break; case IOCTL_GET_PROTECT_PIDS: KdPrint(("IOCTL_GET_PROTECT_PIDS\n")); if (IRP->MdlAddress) { PPID_INFO pUserBuffer = (PPID_INFO)MmGetSystemAddressForMdlSafe(IRP->MdlAddress, NormalPagePriority); ULONG OutputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength; ULONG PIDLength = OutputLength - sizeof(PID_INFO) + sizeof(UINT32);//1025*sizeof(unsigned int),last one for another // add by bh PPID_INFO tmpBuf=(PPID_INFO)ExAllocatePoolWithTag(PagedPool,OutputLength-sizeof(UINT32),'bnak'); if(!tmpBuf) return ntStatus; ///judge safe KdPrint(("entry check hook safe!\n")); if(checkHookSafe()) { KdPrint((" safe!\n")); tmpBuf->count = GetPIDs(tmpBuf->PID, PIDLength / sizeof(UINT32)); tmpBuf->currentTime = __rdtsc(); ULONG bufLength=sizeof(PID_INFO)+tmpBuf->count*sizeof(UINT32); tmpLen = UploadPack((PUCHAR)tmpBuf , bufLength , (PUCHAR)pUserBuffer); } else { KdPrint( (" unfalse\n")); RtlZeroMemory(tmpBuf,OutputLength-sizeof(UINT32)); tmpLen=0; } /// //pUserBuffer->count = GetPIDs(pUserBuffer->PID, PIDLength / sizeof(UINT32)); //pUserBuffer->currentTime = __rdtsc(); ExFreePoolWithTag(tmpBuf,'bnak'); ///// end ntStatus = STATUS_SUCCESS; } break; case IOCTL_SET_SECU_PATHS: KdPrint(("IOCTL_SET_SECU_PATHS\n")); { /////////////////add by bh if(!g_tmpB) setStartTime(); ////////////////end /*PUCHAR pInputBuffer = (PUCHAR)IRP->AssociatedIrp.SystemBuffer; int iStringLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength; ClearSecurePaths(); ULONG index = 0; while(index < iStringLength) { ULONG length = *(PULONG)((ULONG)pInputBuffer + index); index += 4; if(index + length >= iStringLength) break; AddSecurePath((WCHAR*)((ULONG)pInputBuffer + index), length); index += length * 2 + 2; }*/ ntStatus = STATUS_SUCCESS; } break; case IOCTL_SET_SECU_MD5: KdPrint(("IOCTL_SET_SECU_MD5\n")); { PUCHAR pInputBuffer; int iStringLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength; unsigned char * pUnPack=(UCHAR *)ExAllocatePoolWithTag(PagedPool,iStringLength,'knab'); int unPackLength; unPackLength=DownloadUnPack((unsigned char *)IRP->AssociatedIrp.SystemBuffer,pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength,pUnPack); //add by bh //iStringLength=*((ULONG*)pUnPack ); RtlCopyBytes((PVOID)&iStringLength,(PVOID)pUnPack,sizeof(ULONG) ); pInputBuffer=pUnPack+sizeof(ULONG); //if(!g_globalTime) //g_globalTime=*((__int64 *)(pInputBuffer+iStringLength) ); RtlCopyBytes((PVOID)&g_globalTime,(PVOID)(pInputBuffer+iStringLength),8 ); __int64 elapseTime=__rdtsc()-g_globalTime; if( (elapseTime<COMMUNICATE_TIME_LIMIT) && (elapseTime>=COMMUNICATE_TIME_DOWN) ) { KdPrint( ("entry elapse check! ") ); if (unPackLength>0) {KdPrint( ("entry length check! ") ); ClearHash(); for(int i = 0; i <= iStringLength - HASH_SIZE; i += HASH_SIZE) AddSecureHash(pInputBuffer + i); ntStatus = STATUS_SUCCESS; } } ExFreePoolWithTag(pUnPack,'knab'); // } break; case IOCTL_SET_UP_UNLOAD: KdPrint(("IOCTL_SET_UP_UNLOAD\n")); DeviceObject->DriverObject->DriverUnload = DriverUnload; ntStatus = STATUS_SUCCESS; break; } IRP->IoStatus.Status = 0; IRP->IoStatus.Information = tmpLen ; IoCompleteRequest(IRP, IO_NO_INCREMENT); KdPrint(("<==DriverDeviceControl\n")); return ntStatus; }
NTSTATUS IrpCreateFile( IN PUNICODE_STRING FileName, IN ACCESS_MASK DesiredAccess, __out PIO_STATUS_BLOCK IoStatusBlock, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT RealDevice, OUT PFILE_OBJECT *Object ) { NTSTATUS status; KEVENT event; PIRP irp; PIO_STACK_LOCATION irpSp; IO_SECURITY_CONTEXT securityContext; ACCESS_STATE accessState; OBJECT_ATTRIBUTES objectAttributes; PFILE_OBJECT fileObject; AUX_ACCESS_DATA auxData; PAGED_CODE(); RtlZeroMemory(&auxData, sizeof(AUX_ACCESS_DATA)); InitializeObjectAttributes(&objectAttributes, NULL, OBJ_CASE_INSENSITIVE| OBJ_KERNEL_HANDLE, 0, NULL); status = ObCreateObject(KernelMode, *IoFileObjectType, &objectAttributes, KernelMode, NULL, sizeof(FILE_OBJECT), 0, 0, (PVOID *)&fileObject); if (!NT_SUCCESS(status)) { return status; } RtlZeroMemory(fileObject, sizeof(FILE_OBJECT)); fileObject->Type = IO_TYPE_FILE; fileObject->Size = sizeof(FILE_OBJECT); fileObject->DeviceObject = RealDevice; // fileObject->RelatedFileObject = NULL; fileObject->Flags = FO_SYNCHRONOUS_IO; fileObject->FileName.MaximumLength = FileName->MaximumLength; fileObject->FileName.Buffer = (PWCH)ExAllocatePoolWithTag(NonPagedPool, FileName->MaximumLength, 'File'); //fileObject->FileObjectExtension if (fileObject->FileName.Buffer == NULL) { ObDereferenceObject(fileObject); return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(&fileObject->FileName, FileName); KeInitializeEvent(&fileObject->Lock, SynchronizationEvent, FALSE); KeInitializeEvent(&fileObject->Event, NotificationEvent, FALSE); irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (irp == NULL) { ObDereferenceObject(fileObject); return STATUS_INSUFFICIENT_RESOURCES; } KeInitializeEvent(&event, SynchronizationEvent, FALSE); irp->MdlAddress = NULL; irp->Flags |= IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API; irp->RequestorMode = KernelMode; irp->UserIosb = IoStatusBlock; ////LCXL:CHANGE irp->UserEvent = &event; //irp->UserEvent = NULL; irp->PendingReturned = FALSE; irp->Cancel = FALSE; irp->CancelRoutine = NULL; irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread(); irp->Tail.Overlay.AuxiliaryBuffer = NULL; irp->Tail.Overlay.OriginalFileObject = fileObject; status = SeCreateAccessState(&accessState, &auxData, DesiredAccess, IoGetFileObjectGenericMapping()); if (!NT_SUCCESS(status)) { IoFreeIrp(irp); ExFreePool(fileObject->FileName.Buffer); ObDereferenceObject(fileObject); return status; } securityContext.SecurityQos = NULL; securityContext.AccessState = &accessState; securityContext.DesiredAccess = DesiredAccess; securityContext.FullCreateOptions = 0; irpSp = IoGetNextIrpStackLocation(irp); irpSp->MajorFunction = IRP_MJ_CREATE; irpSp->DeviceObject = DeviceObject; irpSp->FileObject = fileObject; irpSp->Parameters.Create.SecurityContext = &securityContext; irpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions; irpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes; irpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess; irpSp->Parameters.Create.EaLength = 0; IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE); status = IoCallDriver(DeviceObject, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL); } status = IoStatusBlock->Status; if (!NT_SUCCESS(status)) { ExFreePool(fileObject->FileName.Buffer); fileObject->FileName.Length = 0; fileObject->DeviceObject = NULL; ObDereferenceObject(fileObject); } else { InterlockedIncrement(&fileObject->DeviceObject->ReferenceCount); if (fileObject->Vpb) { InterlockedIncrement((PLONG)&fileObject->Vpb->ReferenceCount); } *Object = fileObject; KdPrint(("IrpCreateFile:Open file success! object = %x\n", fileObject)); } return status; }
NTSTATUS RamDiskInitializeLogicalUnit( __in PNDAS_LOGICALUNIT_DESCRIPTOR LogicalUnitDescriptor, __in PNDAS_LOGICALUNIT_EXTENSION DeviceExtension) { NTSTATUS status; PRAMDISK_EXTENSION ramDiskExtension; PRAMDISK_DESCRIPTOR ramDiskDescriptor; size_t dataFilePathLength; BOOLEAN newDataFileCreated; PAGED_CODE(); ramDiskExtension = RamDiskGetExtension(DeviceExtension); ramDiskExtension->DeviceExtension = DeviceExtension; if (sizeof(NDAS_LOGICALUNIT_DESCRIPTOR) != LogicalUnitDescriptor->Version) { NdasPortTrace(RAMDISK_INIT, TRACE_LEVEL_FATAL, "LogicalUnitDescriptor version is invalid. Version=%d, Expected=%d\n", LogicalUnitDescriptor->Version, sizeof(NDAS_LOGICALUNIT_DESCRIPTOR)); return STATUS_INVALID_PARAMETER; } if (sizeof(RAMDISK_DESCRIPTOR) != LogicalUnitDescriptor->Size) { NdasPortTrace(RAMDISK_INIT, TRACE_LEVEL_FATAL, "RamDiskDescriptor Size is invalid. Size=%d, Expected=%d\n", LogicalUnitDescriptor->Size, sizeof(RAMDISK_DESCRIPTOR)); return STATUS_INVALID_PARAMETER; } NdasPortTrace(RAMDISK_INIT, TRACE_LEVEL_FATAL, "Initializing RamDisk Logical Unit\n"); ramDiskDescriptor = (PRAMDISK_DESCRIPTOR) LogicalUnitDescriptor; ramDiskExtension->LogicalUnitAddress = LogicalUnitDescriptor->Address; ramDiskExtension->SectorCount = ramDiskDescriptor->SectorCount; ramDiskExtension->SectorSize = ramDiskDescriptor->SectorSize; RamDiskInitializeIoScsiCapabilities( ramDiskExtension, &ramDiskExtension->IoScsiCapabilities); ramDiskExtension->StorageBusType = BusTypeScsi; ramDiskExtension->StorageBusMajorVersion = 2; ramDiskExtension->StorageBusMinorVersion = 0; ramDiskExtension->StorageData = ExAllocatePoolWithTag( NonPagedPool, ramDiskExtension->SectorSize * ramDiskExtension->SectorCount, RAMDISK_EXT_TAG); if (NULL == ramDiskExtension->StorageData) { NdasPortTrace(RAMDISK_INIT, TRACE_LEVEL_WARNING, "RamDisk failed to allocate 0x%X bytes\n", ramDiskExtension->SectorSize * ramDiskExtension->SectorCount); return STATUS_INSUFFICIENT_RESOURCES; } NdasPortTrace(RAMDISK_INIT, TRACE_LEVEL_INFORMATION, "RamDisk created successfully at LogicalUnitAddress=%08X.\n", ramDiskExtension->LogicalUnitAddress.Address); return STATUS_SUCCESS; }
//获取csrss.exe进程 NTSTATUS GetCsrssPid(HANDLE *CsrssPid) { NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; HANDLE Process, hObject; ULONG CsrId = 0; OBJECT_ATTRIBUTES obj; CLIENT_ID cid; POBJECT_NAME_INFORMATION ObjName; UNICODE_STRING ApiPortName; PSYSTEM_HANDLE_INFORMATION_EX Handles; ULONG i; PAGED_CODE(); RtlInitUnicodeString(&ApiPortName, L"\\Windows\\ApiPort"); Handles = (PSYSTEM_HANDLE_INFORMATION_EX)GetInfoTable( SystemHandleInformation ); if( Handles == NULL ) { return STATUS_INSUFFICIENT_RESOURCES; } ObjName = (POBJECT_NAME_INFORMATION)ExAllocatePoolWithTag( PagedPool, 0x2000, INFO_MEM_TAG); KdPrint(("SYS: Number of handles %d\n", Handles->NumberOfHandles)); for(i = 0; i < Handles->NumberOfHandles; i++) { //打开的对象的类型是否为21 Port object if (Handles->Information[i].ObjectTypeNumber == 21) { InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); cid.UniqueProcess = (HANDLE)Handles->Information[i].ProcessId; cid.UniqueThread = 0; ntStatus = ZwOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid); if(NT_SUCCESS(ntStatus)) { ntStatus = ZwDuplicateObject( Process, (HANDLE)Handles->Information[i].Handle, NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS); if(NT_SUCCESS(ntStatus)){ ntStatus = ZwQueryObject(hObject, (OBJECT_INFORMATION_CLASS)ObjectNameInformation, ObjName, 0x2000, NULL); if(NT_SUCCESS(ntStatus)) { if (ObjName->Name.Buffer != NULL) { if (RtlCompareUnicodeString(&ApiPortName, &ObjName->Name, TRUE) == 0) { KdPrint(("SYS: Csrss PID:%d\n", Handles->Information[i].ProcessId)); KdPrint(("SYS: Csrss Port - %wZ\n", &ObjName->Name)); CsrId = Handles->Information[i].ProcessId; } } } else { KdPrint(("SYS: Error in Query Object\n")); } ZwClose(hObject); } else { KdPrint(("SYS: Error on duplicating object\n")); } ZwClose(Process); } else { KdPrint(("SYS: Could not open process\n")); } } } ExFreePoolWithTag( Handles, INFO_MEM_TAG); ExFreePoolWithTag(ObjName, INFO_MEM_TAG); *CsrssPid = (HANDLE)CsrId; return ntStatus; }
NDIS_STATUS SxLibGetPortPropertyUnsafe( _In_ PSX_SWITCH_OBJECT Switch, _In_ NDIS_SWITCH_PORT_ID PortId, _In_ NDIS_SWITCH_PORT_PROPERTY_TYPE PropertyType, _In_opt_ PNDIS_SWITCH_OBJECT_ID PropertyId, _Outptr_ PNDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS *PortPropertyEnumParameters ) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; NDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS propertyParameters; ULONG bytesNeeded = 0; PNDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS outputBuffer = NULL; USHORT outputBufferLength = sizeof(NDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS); propertyParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; propertyParameters.Header.Revision = NDIS_SWITCH_PORT_PROPERTY_ENUM_PARAMETERS_REVISION_1; propertyParameters.PortId = PortId; propertyParameters.PropertyType = PropertyType; propertyParameters.SerializationVersion = NDIS_SWITCH_OBJECT_SERIALIZATION_VERSION_1; // // For Built-in properties, the ID is unnecessary. // if (PropertyId != NULL) { NdisMoveMemory(&propertyParameters.PropertyId, PropertyId, sizeof(NDIS_SWITCH_OBJECT_ID)); } else { ASSERT(PropertyType != NdisSwitchPortPropertyTypeCustom); } outputBuffer = ExAllocatePoolWithTag(NonPagedPoolNx, outputBufferLength, SxExtAllocationTag); if (outputBuffer == NULL) { status = NDIS_STATUS_RESOURCES; goto Cleanup; } do { if (bytesNeeded != 0) { ExFreePoolWithTag(outputBuffer, SxExtAllocationTag); outputBufferLength = (USHORT)bytesNeeded; outputBuffer = ExAllocatePoolWithTag(NonPagedPoolNx, outputBufferLength, SxExtAllocationTag); if (outputBuffer == NULL) { status = NDIS_STATUS_RESOURCES; goto Cleanup; } } if(outputBufferLength >= sizeof(propertyParameters)) { outputBuffer->Header.Size = outputBufferLength; NdisMoveMemory(outputBuffer, &propertyParameters, sizeof(propertyParameters)); } status = SxLibIssueOidRequest(Switch, NdisRequestMethod, OID_SWITCH_PORT_PROPERTY_ENUM, outputBuffer, sizeof(propertyParameters), outputBufferLength, 0, 0, &bytesNeeded); } while(status == NDIS_STATUS_INVALID_LENGTH); Cleanup: if (status != NDIS_STATUS_SUCCESS && outputBuffer != NULL) { ExFreePoolWithTag(outputBuffer, SxExtAllocationTag); outputBuffer = NULL; } *PortPropertyEnumParameters = outputBuffer; return status; }
NTSTATUS GetProcessImageName(HANDLE processId, PUNICODE_STRING ProcessImageName) { NTSTATUS status; ULONG returnedLength; ULONG bufferLength; HANDLE hProcess; PVOID buffer; PEPROCESS eProcess; PUNICODE_STRING imageName; PAGED_CODE(); // this eliminates the possibility of the IDLE Thread/Process status = PsLookupProcessByProcessId(processId, &eProcess); if(NT_SUCCESS(status)) { status = ObOpenObjectByPointer(eProcess,0, NULL, 0,0,KernelMode,&hProcess); if(NT_SUCCESS(status)) { } else { DbgPrint("ObOpenObjectByPointer Failed: %08x\n", status); } ObDereferenceObject(eProcess); } else { DbgPrint("PsLookupProcessByProcessId Failed: %08x\n", status); } if (NULL == ZwQueryInformationProcess) { UNICODE_STRING routineName; RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess"); ZwQueryInformationProcess = (QUERY_INFO_PROCESS) MmGetSystemRoutineAddress(&routineName); if (NULL == ZwQueryInformationProcess) { DbgPrint("Cannot resolve ZwQueryInformationProcess\n"); } } /* Query the actual size of the process path */ status = ZwQueryInformationProcess( hProcess, ProcessImageFileName, NULL, // buffer 0, // buffer size &returnedLength); if (STATUS_INFO_LENGTH_MISMATCH != status) { return status; } /* Check there is enough space to store the actual process path when it is found. If not return an error with the required size */ bufferLength = returnedLength - sizeof(UNICODE_STRING); if (ProcessImageName->MaximumLength < bufferLength) { ProcessImageName->MaximumLength = (USHORT) bufferLength; return STATUS_BUFFER_OVERFLOW; } /* Allocate a temporary buffer to store the path name */ buffer = ExAllocatePoolWithTag(NonPagedPool, returnedLength, PROCESS_POOL_TAG); if (NULL == buffer) { return STATUS_INSUFFICIENT_RESOURCES; } /* Retrieve the process path from the handle to the process */ status = ZwQueryInformationProcess( hProcess, ProcessImageFileName, buffer, returnedLength, &returnedLength); if (NT_SUCCESS(status)) { /* Copy the path name */ imageName = (PUNICODE_STRING) buffer; RtlCopyUnicodeString(ProcessImageName, imageName); } /* Free the temp buffer which stored the path */ ExFreePoolWithTag(buffer, PROCESS_POOL_TAG); return status; }
/* * @implemented */ BOOLEAN NTAPI FsRtlPrivateLock(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN PEPROCESS Process, IN ULONG Key, IN BOOLEAN FailImmediately, IN BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK IoStatus, IN PIRP Irp OPTIONAL, IN PVOID Context OPTIONAL, IN BOOLEAN AlreadySynchronized) { NTSTATUS Status; COMBINED_LOCK_ELEMENT ToInsert; PCOMBINED_LOCK_ELEMENT Conflict; PLOCK_INFORMATION LockInfo; PLOCK_SHARED_RANGE NewSharedRange; BOOLEAN InsertedNew; ULARGE_INTEGER UnsignedStart; ULARGE_INTEGER UnsignedEnd; DPRINT("FsRtlPrivateLock(%wZ, Offset %08x%08x (%d), Length %08x%08x (%d), Key %x, FailImmediately %u, Exclusive %u)\n", &FileObject->FileName, FileOffset->HighPart, FileOffset->LowPart, (int)FileOffset->QuadPart, Length->HighPart, Length->LowPart, (int)Length->QuadPart, Key, FailImmediately, ExclusiveLock); UnsignedStart.QuadPart = FileOffset->QuadPart; UnsignedEnd.QuadPart = FileOffset->QuadPart + Length->QuadPart; if (UnsignedEnd.QuadPart < UnsignedStart.QuadPart) { DPRINT("File offset out of range\n"); IoStatus->Status = STATUS_INVALID_PARAMETER; if (Irp) { DPRINT("Complete lock %p Status %x\n", Irp, IoStatus->Status); FsRtlCompleteLockIrpReal (FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatus->Status, &Status, FileObject); } return FALSE; } /* Initialize the lock, if necessary */ if (!FileLock->LockInformation) { LockInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(LOCK_INFORMATION), TAG_FLOCK); if (!LockInfo) { IoStatus->Status = STATUS_NO_MEMORY; return FALSE; } FileLock->LockInformation = LockInfo; LockInfo->BelongsTo = FileLock; InitializeListHead(&LockInfo->SharedLocks); RtlInitializeGenericTable (&LockInfo->RangeTable, LockCompare, LockAllocate, LockFree, NULL); KeInitializeSpinLock(&LockInfo->CsqLock); InitializeListHead(&LockInfo->CsqList); IoCsqInitializeEx (&LockInfo->Csq, LockInsertIrpEx, LockRemoveIrp, LockPeekNextIrp, LockAcquireQueueLock, LockReleaseQueueLock, LockCompleteCanceledIrp); } LockInfo = FileLock->LockInformation; ToInsert.Exclusive.FileLock.FileObject = FileObject; ToInsert.Exclusive.FileLock.StartingByte = *FileOffset; ToInsert.Exclusive.FileLock.EndingByte.QuadPart = FileOffset->QuadPart + Length->QuadPart; ToInsert.Exclusive.FileLock.ProcessId = Process->UniqueProcessId; ToInsert.Exclusive.FileLock.Key = Key; ToInsert.Exclusive.FileLock.ExclusiveLock = ExclusiveLock; Conflict = RtlInsertElementGenericTable (FileLock->LockInformation, &ToInsert, sizeof(ToInsert), &InsertedNew); if (Conflict && !InsertedNew) { if (Conflict->Exclusive.FileLock.ExclusiveLock || ExclusiveLock) { DPRINT("Conflict %08x%08x:%08x%08x Exc %u (Want Exc %u)\n", Conflict->Exclusive.FileLock.StartingByte.HighPart, Conflict->Exclusive.FileLock.StartingByte.LowPart, Conflict->Exclusive.FileLock.EndingByte.HighPart, Conflict->Exclusive.FileLock.EndingByte.LowPart, Conflict->Exclusive.FileLock.ExclusiveLock, ExclusiveLock); if (FailImmediately) { DPRINT("STATUS_FILE_LOCK_CONFLICT\n"); IoStatus->Status = STATUS_FILE_LOCK_CONFLICT; if (Irp) { DPRINT("STATUS_FILE_LOCK_CONFLICT: Complete\n"); FsRtlCompleteLockIrpReal (FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatus->Status, &Status, FileObject); } return FALSE; } else { IoStatus->Status = STATUS_PENDING; if (Irp) { Irp->IoStatus.Information = LockInfo->Generation; IoMarkIrpPending(Irp); IoCsqInsertIrpEx (&LockInfo->Csq, Irp, NULL, NULL); } } return FALSE; } else { ULONG i; /* We know of at least one lock in range that's shared. We need to * find out if any more exist and any are exclusive. */ for (i = 0; i < RtlNumberGenericTableElements(&LockInfo->RangeTable); i++) { Conflict = RtlGetElementGenericTable(&LockInfo->RangeTable, i); /* The first argument will be inserted as a shared range */ if (Conflict && (LockCompare(&LockInfo->RangeTable, Conflict, &ToInsert) == GenericEqual)) { if (Conflict->Exclusive.FileLock.ExclusiveLock) { /* Found an exclusive match */ if (FailImmediately) { IoStatus->Status = STATUS_FILE_LOCK_CONFLICT; DPRINT("STATUS_FILE_LOCK_CONFLICT\n"); if (Irp) { DPRINT("STATUS_FILE_LOCK_CONFLICT: Complete\n"); FsRtlCompleteLockIrpReal (FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatus->Status, &Status, FileObject); } } else { IoStatus->Status = STATUS_PENDING; if (Irp) { IoMarkIrpPending(Irp); IoCsqInsertIrpEx (&LockInfo->Csq, Irp, NULL, NULL); } } return FALSE; } } } DPRINT("Overlapping shared lock %wZ %08x%08x %08x%08x\n", &FileObject->FileName, Conflict->Exclusive.FileLock.StartingByte.HighPart, Conflict->Exclusive.FileLock.StartingByte.LowPart, Conflict->Exclusive.FileLock.EndingByte.HighPart, Conflict->Exclusive.FileLock.EndingByte.LowPart); Conflict = FsRtlpRebuildSharedLockRange(FileLock, LockInfo, &ToInsert); if (!Conflict) { IoStatus->Status = STATUS_NO_MEMORY; if (Irp) { FsRtlCompleteLockIrpReal (FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatus->Status, &Status, FileObject); } } /* We got here because there were only overlapping shared locks */ /* A shared lock is both a range *and* a list entry. Insert the entry here. */ DPRINT("Adding shared lock %wZ\n", &FileObject->FileName); NewSharedRange = ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), TAG_RANGE); if (!NewSharedRange) { IoStatus->Status = STATUS_NO_MEMORY; if (Irp) { FsRtlCompleteLockIrpReal (FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatus->Status, &Status, FileObject); } return FALSE; } DPRINT("Adding shared lock %wZ\n", &FileObject->FileName); NewSharedRange->Start = *FileOffset; NewSharedRange->End.QuadPart = FileOffset->QuadPart + Length->QuadPart; NewSharedRange->Key = Key; NewSharedRange->ProcessId = ToInsert.Exclusive.FileLock.ProcessId; InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry); DPRINT("Acquired shared lock %wZ %08x%08x %08x%08x\n", &FileObject->FileName, Conflict->Exclusive.FileLock.StartingByte.HighPart, Conflict->Exclusive.FileLock.StartingByte.LowPart, Conflict->Exclusive.FileLock.EndingByte.HighPart, Conflict->Exclusive.FileLock.EndingByte.LowPart); IoStatus->Status = STATUS_SUCCESS; if (Irp) { FsRtlCompleteLockIrpReal (FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatus->Status, &Status, FileObject); } return TRUE; } } else if (!Conflict) { /* Conflict here is (or would be) the newly inserted element, but we ran * out of space probably. */ IoStatus->Status = STATUS_NO_MEMORY; if (Irp) { FsRtlCompleteLockIrpReal (FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatus->Status, &Status, FileObject); } return FALSE; } else { DPRINT("Inserted new lock %wZ %08x%08x %08x%08x exclusive %u\n", &FileObject->FileName, Conflict->Exclusive.FileLock.StartingByte.HighPart, Conflict->Exclusive.FileLock.StartingByte.LowPart, Conflict->Exclusive.FileLock.EndingByte.HighPart, Conflict->Exclusive.FileLock.EndingByte.LowPart, Conflict->Exclusive.FileLock.ExclusiveLock); if (!ExclusiveLock) { NewSharedRange = ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), TAG_RANGE); if (!NewSharedRange) { IoStatus->Status = STATUS_NO_MEMORY; if (Irp) { FsRtlCompleteLockIrpReal (FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatus->Status, &Status, FileObject); } return FALSE; } DPRINT("Adding shared lock %wZ\n", &FileObject->FileName); NewSharedRange->Start = *FileOffset; NewSharedRange->End.QuadPart = FileOffset->QuadPart + Length->QuadPart; NewSharedRange->Key = Key; NewSharedRange->ProcessId = Process->UniqueProcessId; InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry); } /* Assume all is cool, and lock is set */ IoStatus->Status = STATUS_SUCCESS; if (Irp) { /* Complete the request */ FsRtlCompleteLockIrpReal(FileLock->CompleteLockIrpRoutine, Context, Irp, IoStatus->Status, &Status, FileObject); /* Update the status */ IoStatus->Status = Status; } } return TRUE; }
/* Process Callback that is called every time a process event occurs. Creates a kernel event which can be used to notify userspace processes. */ VOID ProcessCallback( IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate ) { NTSTATUS status; LARGE_INTEGER currentSystemTime; LARGE_INTEGER currentLocalTime; TIME_FIELDS timeFields; UNICODE_STRING processImagePath; PROCESS_EVENT_PACKET* processEventPacket; PCAPTURE_PROCESS_MANAGER pProcessManager; /* Get the current time */ KeQuerySystemTime(¤tSystemTime); ExSystemTimeToLocalTime(¤tSystemTime,¤tLocalTime); RtlTimeToTimeFields(¤tLocalTime,&timeFields); /* Get the process manager from the device extension */ pProcessManager = gpDeviceObject->DeviceExtension; processEventPacket = ExAllocatePoolWithTag(NonPagedPool, sizeof(PROCESS_EVENT_PACKET), PROCESS_POOL_TAG); if(processEventPacket == NULL) { return; } RtlCopyMemory(&processEventPacket->processEvent.time, &timeFields, sizeof(TIME_FIELDS)); processImagePath.Length = 0; processImagePath.MaximumLength = 0; status = GetProcessImageName(hProcessId, &processImagePath); if(status == STATUS_BUFFER_OVERFLOW) { processImagePath.Buffer = ExAllocatePoolWithTag(NonPagedPool, processImagePath.MaximumLength, PROCESS_POOL_TAG); if(processImagePath.Buffer != NULL) { status = GetProcessImageName(hProcessId, &processImagePath); if(NT_SUCCESS(status)) { DbgPrint("CaptureProcessMonitor: %i %i=>%i:%wZ\n", bCreate, hParentId, hProcessId, &processImagePath); RtlStringCbCopyUnicodeString(processEventPacket->processEvent.processPath, 1024, &processImagePath); } ExFreePoolWithTag(processImagePath.Buffer,PROCESS_POOL_TAG); } } processEventPacket->processEvent.hParentProcessId = hParentId; processEventPacket->processEvent.hProcessId = hProcessId; processEventPacket->processEvent.bCreated = bCreate; // Queue the process event ExInterlockedInsertTailList(&pProcessManager->lQueuedProcessEvents, &processEventPacket->Link, &pProcessManager->lQueuedProcessEventsSpinLock); pProcessManager->nQueuedProcessEvents++; KeSetEvent(pProcessManager->eNewProcessEvent, 0, FALSE); KeClearEvent(pProcessManager->eNewProcessEvent); }
NTSTATUS ReceiveNdfsWinxpMessage ( IN PPRIMARY_SESSION PrimarySession, IN _U16 Mid ) { PNDFS_REQUEST_HEADER ndfsRequestHeader = (PNDFS_REQUEST_HEADER)PrimarySession->Thread.SessionSlot[Mid].RequestMessageBuffer; PNDFS_WINXP_REQUEST_HEADER ndfsWinxpRequestHeader; _U8 *cryptWinxpRequestMessage; NTSTATUS tdiStatus; #if __NDAS_FAT_DES__ int desResult; #endif cryptWinxpRequestMessage = PrimarySession->Thread.SessionSlot[Mid].CryptWinxpMessageBuffer; //ASSERT(ndfsRequestHeader->Splitted == 0 && ndfsRequestHeader->MessageSecurity == 0); if (ndfsRequestHeader->Splitted == 0) { ASSERT( ndfsRequestHeader->MessageSize <= PrimarySession->Thread.SessionSlot[Mid].RequestMessageBufferLength ); ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(ndfsRequestHeader+1); if (ndfsRequestHeader->MessageSecurity == 0) { tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject, (_U8 *)ndfsWinxpRequestHeader, ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER), NULL ); PrimarySession->Thread.SessionSlot[Mid].NdfsWinxpRequestHeader = ndfsWinxpRequestHeader; return tdiStatus; } ASSERT(ndfsRequestHeader->MessageSecurity == 1); tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject, cryptWinxpRequestMessage, sizeof(NDFS_WINXP_REQUEST_HEADER), NULL ); if (tdiStatus != STATUS_SUCCESS) { return tdiStatus; } #if __NDAS_FAT_DES__ RtlZeroMemory(&PrimarySession->DesCbcContext, sizeof(PrimarySession->DesCbcContext)); RtlZeroMemory(PrimarySession->Iv, sizeof(PrimarySession->Iv)); //DES_CBCInit(&PrimarySession->DesCbcContext, PrimarySession->NetdiskPartition->NetdiskPartitionInformation.NetdiskInformation.Password, PrimarySession->Iv, DES_DECRYPT); DES_CBCInit(&PrimarySession->DesCbcContext, PrimarySession->NetdiskPartitionInformation.NetdiskInformation.Password, PrimarySession->Iv, DES_DECRYPT); desResult = DES_CBCUpdate(&PrimarySession->DesCbcContext, (_U8 *)ndfsWinxpRequestHeader, cryptWinxpRequestMessage, sizeof(NDFS_WINXP_REQUEST_HEADER)); ASSERT(desResult == IDOK); #endif if (ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER)) { if (ndfsWinxpRequestHeader->IrpMajorFunction == IRP_MJ_WRITE && ndfsRequestHeader->RwDataSecurity == 0) { tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject, (_U8 *)(ndfsWinxpRequestHeader+1), ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER), NULL ); if (tdiStatus != STATUS_SUCCESS) { return tdiStatus; } } else { tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject, cryptWinxpRequestMessage, ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER), NULL ); if (tdiStatus != STATUS_SUCCESS) { return tdiStatus; } #if __NDAS_FAT_DES__ desResult = DES_CBCUpdate(&PrimarySession->DesCbcContext, (_U8 *)(ndfsWinxpRequestHeader+1), cryptWinxpRequestMessage, ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER)); ASSERT(desResult == IDOK); #endif } } PrimarySession->Thread.SessionSlot[Mid].NdfsWinxpRequestHeader = ndfsWinxpRequestHeader; return STATUS_SUCCESS; } ASSERT( ndfsRequestHeader->Splitted == 1 ); // if (ndfsRequestHeader->MessageSize > (PrimarySession->RequestMessageBufferLength - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER))) { PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePoolLength = ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER); PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool = ExAllocatePoolWithTag( NonPagedPool, PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePoolLength, PRIMARY_SESSION_BUFFERE_TAG ); ASSERT(PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool); if (PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool == NULL) { DebugTrace2( 0, Dbg, ("ReceiveNdfsWinxpMessage: failed to allocate ExtendWinxpRequestMessagePool\n")); return STATUS_INSUFFICIENT_RESOURCES; } ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool); } // else // ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(ndfsRequestHeader+1); if (ndfsRequestHeader->MessageSecurity == 0) { tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject, (_U8 *)ndfsWinxpRequestHeader, sizeof(NDFS_WINXP_REQUEST_HEADER), NULL ); if (tdiStatus != STATUS_SUCCESS) { return tdiStatus; } } else { tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject, cryptWinxpRequestMessage, sizeof(NDFS_WINXP_REQUEST_HEADER), NULL ); if (tdiStatus != STATUS_SUCCESS) { return tdiStatus; } #if __NDAS_FAT_DES__ RtlZeroMemory(&PrimarySession->DesCbcContext, sizeof(PrimarySession->DesCbcContext)); RtlZeroMemory(PrimarySession->Iv, sizeof(PrimarySession->Iv)); //DES_CBCInit(&PrimarySession->DesCbcContext, PrimarySession->NetdiskPartition->NetdiskPartitionInformation.NetdiskInformation.Password, PrimarySession->Iv, DES_DECRYPT); DES_CBCInit(&PrimarySession->DesCbcContext, PrimarySession->NetdiskPartitionInformation.NetdiskInformation.Password, PrimarySession->Iv, DES_DECRYPT); desResult = DES_CBCUpdate(&PrimarySession->DesCbcContext, (_U8 *)ndfsWinxpRequestHeader, cryptWinxpRequestMessage, sizeof(NDFS_WINXP_REQUEST_HEADER)); ASSERT(desResult == IDOK); #endif } while(1) { PNDFS_REQUEST_HEADER splitNdfsRequestHeader = &PrimarySession->Thread.SessionSlot[Mid].SplitNdfsRequestHeader; tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject, (_U8 *)splitNdfsRequestHeader, sizeof(NDFS_REQUEST_HEADER), NULL ); if (tdiStatus != STATUS_SUCCESS) return tdiStatus; if (!( PrimarySession->Thread.SessionState == SESSION_SETUP && ndfsRequestHeader->Uid == PrimarySession->SessionContext.Uid && ndfsRequestHeader->Tid == PrimarySession->SessionContext.Tid )) { ASSERT(NDASFAT_BUG); return STATUS_UNSUCCESSFUL; } if (ndfsRequestHeader->MessageSecurity == 0) { tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject, (_U8 *)ndfsWinxpRequestHeader + ndfsRequestHeader->MessageSize - splitNdfsRequestHeader->MessageSize, splitNdfsRequestHeader->Splitted ? PrimarySession->SessionContext.PrimaryMaxDataSize : (splitNdfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER)), NULL ); if (tdiStatus != STATUS_SUCCESS) return tdiStatus; } else { tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject, cryptWinxpRequestMessage, splitNdfsRequestHeader->Splitted ? PrimarySession->SessionContext.PrimaryMaxDataSize : (splitNdfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER)), NULL ); if (tdiStatus != STATUS_SUCCESS) return tdiStatus; #if __NDAS_FAT_DES__ desResult = DES_CBCUpdate( &PrimarySession->DesCbcContext, (_U8 *)ndfsWinxpRequestHeader + ndfsRequestHeader->MessageSize - splitNdfsRequestHeader->MessageSize, cryptWinxpRequestMessage, splitNdfsRequestHeader->Splitted ? PrimarySession->SessionContex.PrimaryMaxDataSize : (splitNdfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER)) ); ASSERT(desResult == IDOK); #endif } if (splitNdfsRequestHeader->Splitted) continue; PrimarySession->Thread.SessionSlot[Mid].NdfsWinxpRequestHeader = ndfsWinxpRequestHeader; return STATUS_SUCCESS; } }
NTSTATUS FsRtlGetTunnelParameterValue ( 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 Tunnel parameter information and get the value. Arguments: ValueName - the unicode name for the registry value located in the double space configuration location of 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 = TUNNEL_KEY_NAME; KeyName.Length = sizeof(TUNNEL_KEY_NAME) - sizeof(WCHAR); KeyName.MaximumLength = sizeof(TUNNEL_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); 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, 'KnuT'); if (!KeyValueInformation) { 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; }
NTSTATUS NTAPI SeLocateProcessImageName(IN PEPROCESS Process, OUT PUNICODE_STRING *ProcessImageName) { POBJECT_NAME_INFORMATION AuditName; PUNICODE_STRING ImageName; PFILE_OBJECT FileObject; NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); /* Assume failure */ *ProcessImageName = NULL; /* Check if we have audit info */ AuditName = Process->SeAuditProcessCreationInfo.ImageFileName; if (!AuditName) { /* Get the file object */ Status = PsReferenceProcessFilePointer(Process, &FileObject); if (!NT_SUCCESS(Status)) return Status; /* Initialize the audit structure */ Status = SeInitializeProcessAuditName(FileObject, TRUE, &AuditName); if (NT_SUCCESS(Status)) { /* Set it */ if (InterlockedCompareExchangePointer((PVOID*)&Process-> SeAuditProcessCreationInfo.ImageFileName, AuditName, NULL)) { /* Someone beat us to it, deallocate our copy */ ExFreePool(AuditName); } } /* Dereference the file object */ ObDereferenceObject(FileObject); if (!NT_SUCCESS(Status)) return Status; } /* Get audit info again, now we have it for sure */ AuditName = Process->SeAuditProcessCreationInfo.ImageFileName; /* Allocate the output string */ ImageName = ExAllocatePoolWithTag(NonPagedPool, AuditName->Name.MaximumLength + sizeof(UNICODE_STRING), TAG_SEPA); if (!ImageName) return STATUS_NO_MEMORY; /* Make a copy of it */ RtlCopyMemory(ImageName, &AuditName->Name, AuditName->Name.MaximumLength + sizeof(UNICODE_STRING)); /* Fix up the buffer */ ImageName->Buffer = (PWSTR)(ImageName + 1); /* Return it */ *ProcessImageName = ImageName; /* Return status */ return Status; }
VOID FsRtlAddToTunnelCache ( IN PTUNNEL Cache, IN ULONGLONG DirKey, IN PUNICODE_STRING ShortName, IN PUNICODE_STRING LongName, IN BOOLEAN KeyByShortName, IN ULONG DataLength, IN PVOID Data ) /*++ Routine Description: Adds an entry to the tunnel cache keyed by DirectoryKey ## (KeyByShortName ? ShortName : LongName) ShortName, LongName, and Data are copied and stored in the tunnel. As a side effect, if there are too many entries in the tunnel cache, this routine will initiate expiration in the tunnel cache. Arguments: Cache - a tunnel cache initialized by FsRtlInitializeTunnelCache() DirKey - the key value of the directory the name appeared in ShortName - (optional if !KeyByShortName) the 8.3 name of the file LongName - (optional if KeyByShortName) the long name of the file KeyByShortName - specifies which name is keyed in the tunnel cache DataLength - specifies the length of the opaque data segment (file system specific) which contains the tunnelling information for this file Data - pointer to the opaque tunneling data segment Return Value: None --*/ { LONG Compare; ULONG NodeSize; PUNICODE_STRING NameKey; PRTL_SPLAY_LINKS *Links; LIST_ENTRY FreePoolList; PTUNNEL_NODE Node = NULL; PTUNNEL_NODE NewNode = NULL; BOOLEAN FreeOldNode = FALSE; BOOLEAN AllocatedFromPool = FALSE; PAGED_CODE(); // // If MaxEntries is 0 then tunneling is disabled. // if (TunnelMaxEntries == 0) return; InitializeListHead(&FreePoolList); // // Grab a new node for this data // NodeSize = sizeof(TUNNEL_NODE) + ShortName->Length + LongName->Length + DataLength; if (LOOKASIDE_NODE_SIZE >= NodeSize) { NewNode = ExAllocateFromPagedLookasideList(&TunnelLookasideList); } if (NewNode == NULL) { // // Data doesn't fit in lookaside nodes // NewNode = ExAllocatePoolWithTag(PagedPool, NodeSize, 'PnuT'); if (NewNode == NULL) { // // Give up tunneling this entry // return; } AllocatedFromPool = TRUE; } // // Traverse the cache to find our insertion point // NameKey = (KeyByShortName ? ShortName : LongName); ExAcquireFastMutex(&Cache->Mutex); Links = &Cache->Cache; while (*Links) { Node = CONTAINING_RECORD(*Links, TUNNEL_NODE, CacheLinks); Compare = FsRtlCompareNodeAndKey(Node, DirKey, NameKey); if (Compare > 0) { Links = &RtlLeftChild(&Node->CacheLinks); } else { if (Compare < 0) { Links = &RtlRightChild(&Node->CacheLinks); } else { break; } } } // // Thread new data into the splay tree // RtlInitializeSplayLinks(&NewNode->CacheLinks); if (Node) { // // Not inserting first node in tree // if (*Links) { // // Entry exists in the cache, so replace by swapping all splay links // RtlRightChild(&NewNode->CacheLinks) = RtlRightChild(*Links); RtlLeftChild(&NewNode->CacheLinks) = RtlLeftChild(*Links); if (RtlRightChild(*Links)) RtlParent(RtlRightChild(*Links)) = &NewNode->CacheLinks; if (RtlLeftChild(*Links)) RtlParent(RtlLeftChild(*Links)) = &NewNode->CacheLinks; if (!RtlIsRoot(*Links)) { // // Change over the parent links. Note that we've messed with *Links now // since it is pointing at the parent member. // RtlParent(&NewNode->CacheLinks) = RtlParent(*Links); if (RtlIsLeftChild(*Links)) { RtlLeftChild(RtlParent(*Links)) = &NewNode->CacheLinks; } else { RtlRightChild(RtlParent(*Links)) = &NewNode->CacheLinks; } } else { // // Set root of the cache // Cache->Cache = &NewNode->CacheLinks; } // // Free old node // RemoveEntryList(&Node->ListLinks); FsRtlFreeTunnelNode(Node, &FreePoolList); Cache->NumEntries--; } else { // // Simple insertion as a leaf // NewNode->CacheLinks.Parent = &Node->CacheLinks; *Links = &NewNode->CacheLinks; } } else { Cache->Cache = &NewNode->CacheLinks; } // // Thread onto the timer list // FsRtlQueryNormalizedSystemTime(&NewNode->CreateTime); InsertTailList(&Cache->TimerQueue, &NewNode->ListLinks); Cache->NumEntries++; // // Stash tunneling information // NewNode->DirKey = DirKey; if (KeyByShortName) { NewNode->Flags = TUNNEL_FLAG_KEY_SHORT; } else { NewNode->Flags = 0; } // // Initialize the internal UNICODE_STRINGS to point at the buffer segments. For various // reasons (UNICODE APIs are incomplete, we're avoiding calling any allocate routine more // than once, UNICODE strings are not guaranteed to be null terminated) we have to do a lot // of this by hand. // // The data is layed out like this in the allocated block: // // ----------------------------------------------------------------------------------- // | TUNNEL_NODE | Node->ShortName.Buffer | Node->LongName.Buffer | Node->TunnelData | // ----------------------------------------------------------------------------------- // NewNode->ShortName.Buffer = (PWCHAR)((PCHAR)NewNode + sizeof(TUNNEL_NODE)); NewNode->LongName.Buffer = (PWCHAR)((PCHAR)NewNode + sizeof(TUNNEL_NODE) + ShortName->Length); NewNode->ShortName.Length = NewNode->ShortName.MaximumLength = ShortName->Length; NewNode->LongName.Length = NewNode->LongName.MaximumLength = LongName->Length; if (ShortName->Length) { RtlCopyMemory(NewNode->ShortName.Buffer, ShortName->Buffer, ShortName->Length); } if (LongName->Length) { RtlCopyMemory(NewNode->LongName.Buffer, LongName->Buffer, LongName->Length); } NewNode->TunnelData = (PVOID)((PCHAR)NewNode + sizeof(TUNNEL_NODE) + ShortName->Length + LongName->Length); NewNode->TunnelDataLength = DataLength; RtlCopyMemory(NewNode->TunnelData, Data, DataLength); if (AllocatedFromPool) { SetFlag(NewNode->Flags, TUNNEL_FLAG_NON_LOOKASIDE); } #if defined(TUNNELTEST) || defined (KEYVIEW) DbgPrint("FsRtlAddToTunnelCache:\n"); DumpNode(NewNode, 1); #ifndef KEYVIEW DumpTunnel(Cache); #endif #endif // TUNNELTEST // // Clean out the cache, release, and then drop any pool memory we need to // FsRtlPruneTunnelCache(Cache, &FreePoolList); ExReleaseFastMutex(&Cache->Mutex); FsRtlEmptyFreePoolList(&FreePoolList); return; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Parses received PIDs IOCTL from analyzer.py and adds ths PIDs in the hidden and monitored // lists. // Parameters : // IRP buffer data. // Return value : // NTSTATUS : STATUS_SUCCESS on success. ////////////////////////////////////////////////////////////////////////////////////////////////////////////// NTSTATUS parse_pids(PCHAR pids) { PCHAR start = NULL, current = NULL, data = NULL; ULONG len, pid; int nb_pid = 0; NTSTATUS status; if(pids == NULL) return STATUS_INVALID_PARAMETER; status = RtlStringCbLengthA(pids, MAXSIZE, &len); if(!NT_SUCCESS(status)) return status; data = ExAllocatePoolWithTag(NonPagedPool, len+1, TEMP_TAG); if(data == NULL) return STATUS_NO_MEMORY; status = RtlStringCbPrintfA(data, len+1, "%s", pids); if(!NT_SUCCESS(status)) { ExFreePool(data); return status; } start = data; current = data; while(*current != 0x00) { if(*current == '_' && current!=start) { *current = 0x00; status = RtlCharToInteger(start, 10, &pid); if(NT_SUCCESS(status) && pid!=0) { if(!nb_pid) { startMonitoringProcess(pid); } else if(nb_pid == 1) { if(pid) addHiddenProcess(pid); hook_ssdt(pid); } else { if(pid) addHiddenProcess(pid); } nb_pid++; } start = current+1; } current++; } if(start != current) { status = RtlCharToInteger(start, 10, &pid); if(NT_SUCCESS(status) && pid!=0) { if(!nb_pid) startMonitoringProcess(pid); else if(nb_pid == 1) { if(pid) addHiddenProcess(pid); hook_ssdt(pid); } else addHiddenProcess(pid); } } ExFreePool(data); return STATUS_SUCCESS; }
/* Source: WDK/src_5239/kmdf/1394/isochapi.c, line 679. */ NTSTATUS t1394_IsochFreeResources( PDEVICE_EXTENSION deviceExtension, /* added for SLAyer */ /* IN WDFDEVICE Device, */ /* IN WDFREQUEST Request, */ /* IN */ HANDLE hResource ) { NTSTATUS ntStatus = STATUS_SUCCESS; /* PDEVICE_EXTENSION deviceExtension = GetDeviceContext(Device); */ PIRB pIrb = NULL; PISOCH_RESOURCE_DATA IsochResourceData = NULL; PLIST_ENTRY listHead; PLIST_ENTRY thisEntry; /* ENTER("t1394_IsochFreeResources"); */ /* TRACE(TL_TRACE, ("hResource = 0x%x\n", hResource)); */ pIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), POOLTAG_1394); if (!pIrb) { /* TRACE(TL_ERROR, ("Failed to allocate pIrb!\n")); */ ntStatus = STATUS_INSUFFICIENT_RESOURCES; goto Exit_IsochFreeResources; } // if // remove this one from our list... WdfSpinLockAcquire(deviceExtension->IsochResourceSpinLock); listHead = &deviceExtension->IsochResourceData; for(thisEntry = listHead->Flink; thisEntry != listHead; IsochResourceData = NULL, thisEntry = thisEntry->Flink) { IsochResourceData = CONTAINING_RECORD(thisEntry, ISOCH_RESOURCE_DATA, IsochResourceList); if (IsochResourceData->hResource == hResource) { /* TRACE(TL_TRACE, ("Removing hResource = 0x%x\n", hResource)); */ RemoveEntryList(&IsochResourceData->IsochResourceList); ExFreePool(IsochResourceData); break; } } WdfSpinLockRelease(deviceExtension->IsochResourceSpinLock); RtlZeroMemory (pIrb, sizeof (IRB)); /* pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES; */ pIrb->Flags = 0; /* pIrb->u.IsochFreeResources.hResource = hResource; */ /* ntStatus = t1394_SubmitIrpSynch(deviceExtension->StackIoTarget, Request, pIrb); */ if (!NT_SUCCESS(ntStatus)) { /* TRACE(TL_ERROR, ("SubmitIrpSync failed = 0x%x\n", ntStatus)); */ } Exit_IsochFreeResources: if (pIrb) { ExFreePool(pIrb); } /* EXIT("t1394_IsochFreeResources", ntStatus); */ return(ntStatus); } // t1394_IsochFreeResources
BOOLEAN NtfsAcquireScbForReadAhead ( IN PVOID OpaqueScb, IN BOOLEAN Wait ) /*++ Routine Description: The address of this routine is specified when creating a CacheMap for a file. It is subsequently called by the Lazy Writer prior to its performing read ahead to the file. Arguments: Scb - The Scb which was specified as a context parameter for this routine. Wait - TRUE if the caller is willing to block. Return Value: FALSE - if Wait was specified as FALSE and blocking would have been required. The Fcb is not acquired. TRUE - if the Scb has been acquired --*/ { PREAD_AHEAD_THREAD ReadAheadThread; PVOID CurrentThread; KIRQL OldIrql; PSCB Scb = (PSCB)OpaqueScb; PFCB Fcb = Scb->Fcb; BOOLEAN AcquiredFile = FALSE; ASSERT_SCB(Scb); // // Acquire the Scb only for those files that the read wil // acquire it for, i.e., not the first set of system files. // Otherwise we can deadlock, for example with someone needing // a new Mft record. // if ((Scb->Header.PagingIoResource == NULL) || ExAcquireResourceShared( Scb->Header.PagingIoResource, Wait )) { AcquiredFile = TRUE; // // Add our thread to the read ahead list. // KeAcquireSpinLock( &NtfsData.StrucSupSpinLock, &OldIrql ); CurrentThread = (PVOID)PsGetCurrentThread(); ReadAheadThread = (PREAD_AHEAD_THREAD)NtfsData.ReadAheadThreads.Flink; while ((ReadAheadThread != (PREAD_AHEAD_THREAD)&NtfsData.ReadAheadThreads) && (ReadAheadThread->Thread != NULL)) { // // We better not already see ourselves. // ASSERT( ReadAheadThread->Thread != CurrentThread ); ReadAheadThread = (PREAD_AHEAD_THREAD)ReadAheadThread->Links.Flink; } // // If we hit the end of the list, then allocate a new one. Note we // should have at most one entry per critical worker thread in the // system. // if (ReadAheadThread == (PREAD_AHEAD_THREAD)&NtfsData.ReadAheadThreads) { ReadAheadThread = ExAllocatePoolWithTag( NonPagedPool, sizeof(READ_AHEAD_THREAD), 'RftN' ); // // If we failed to allocate an entry, clean up and raise. // if (ReadAheadThread == NULL) { KeReleaseSpinLock( &NtfsData.StrucSupSpinLock, OldIrql ); if (NtfsSegmentNumber( &Fcb->FileReference ) > VOLUME_DASD_NUMBER) { if (Scb->Header.PagingIoResource != NULL) { ExReleaseResource( Scb->Header.PagingIoResource ); } } ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES ); } InsertTailList( &NtfsData.ReadAheadThreads, &ReadAheadThread->Links ); } ReadAheadThread->Thread = CurrentThread; KeReleaseSpinLock( &NtfsData.StrucSupSpinLock, OldIrql ); } return AcquiredFile; }
BOOLEAN INIT_FUNCTION NTAPI SepInitSDs(VOID) { /* Create PublicDefaultSd */ SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicDefaultSd == NULL) return FALSE; RtlCreateSecurityDescriptor(SePublicDefaultSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicDefaultSd, TRUE, SePublicDefaultDacl, FALSE); /* Create PublicDefaultUnrestrictedSd */ SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicDefaultUnrestrictedSd == NULL) return FALSE; RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd, TRUE, SePublicDefaultUnrestrictedDacl, FALSE); /* Create PublicOpenSd */ SePublicOpenSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicOpenSd == NULL) return FALSE; RtlCreateSecurityDescriptor(SePublicOpenSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicOpenSd, TRUE, SePublicOpenDacl, FALSE); /* Create PublicOpenUnrestrictedSd */ SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SePublicOpenUnrestrictedSd == NULL) return FALSE; RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd, TRUE, SePublicOpenUnrestrictedDacl, FALSE); /* Create SystemDefaultSd */ SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SeSystemDefaultSd == NULL) return FALSE; RtlCreateSecurityDescriptor(SeSystemDefaultSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SeSystemDefaultSd, TRUE, SeSystemDefaultDacl, FALSE); /* Create UnrestrictedSd */ SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_DESCRIPTOR), TAG_SD); if (SeUnrestrictedSd == NULL) return FALSE; RtlCreateSecurityDescriptor(SeUnrestrictedSd, SECURITY_DESCRIPTOR_REVISION); RtlSetDaclSecurityDescriptor(SeUnrestrictedSd, TRUE, SeUnrestrictedDacl, FALSE); return TRUE; }