ULONG CounterInsertGroup( IN PDIALOG_OBJECT Object ) { PLIST_ENTRY ListHead; PLIST_ENTRY ListEntry; PMSP_DTL_OBJECT DtlObject; PCOUNTER_CONTEXT Context; PTREELIST_OBJECT TreeList; PMSP_COUNTER_GROUP Group; TVINSERTSTRUCT tvi = {0}; HTREEITEM hItemGroup; HTREEITEM hItemRoot; HWND hWndTree; PMSP_COUNTER_OBJECT Counter; ULONG Count; Context = SdkGetContext(Object, COUNTER_CONTEXT); DtlObject = Context->DtlObject; TreeList = Context->TreeList; hWndTree = TreeList->hWndTree; MspReferenceCounterObject(DtlObject, &Counter); Context->Counter = Counter; if (IsListEmpty(&Counter->GroupListHead)) { return 0; } Count = 0; // // Insert unique root node // tvi.hParent = NULL; tvi.hInsertAfter = TVI_ROOT; tvi.item.mask = TVIF_TEXT | TVIF_PARAM; tvi.item.pszText = Counter->Name; tvi.item.lParam = (LPARAM)Counter; hItemRoot = TreeView_InsertItem(hWndTree, &tvi); // // Insert process group // hItemGroup = hItemRoot; ListHead = &Counter->GroupListHead; ListEntry = ListHead->Flink; while (ListEntry != ListHead) { Group = CONTAINING_RECORD(ListEntry, MSP_COUNTER_GROUP, ListEntry); tvi.hParent = hItemRoot; tvi.hInsertAfter = hItemGroup; tvi.item.mask = TVIF_TEXT | TVIF_PARAM; tvi.item.pszText = Group->Name; tvi.item.lParam = (LPARAM)Group; hItemGroup = TreeView_InsertItem(hWndTree, &tvi); CounterInsertEntry(hWndTree, hItemGroup, Group); ListEntry = ListEntry->Flink; Count += 1; } return Count; }
/*-------------------------------------------------------------------*/ int bind_device_ex (DEVBLK* dev, char* spec, ONCONNECT fn, void* arg ) { bind_struct* bs; int was_list_empty; if (!init_done) init_sockdev(); if (sysblk.shutdown) return 0; logdebug("bind_device (%4.4X, %s)\n", dev->devnum, spec); /* Error if device already bound */ if (dev->bs) { logmsg (_("HHCSD001E Device %4.4X already bound to socket %s\n"), dev->devnum, dev->bs->spec); return 0; /* (failure) */ } /* Create a new bind_struct entry */ bs = malloc(sizeof(bind_struct)); if (!bs) { logmsg (_("HHCSD002E bind_device malloc() failed for device %4.4X\n"), dev->devnum); return 0; /* (failure) */ } memset(bs,0,sizeof(bind_struct)); bs->fn = fn; bs->arg = arg; if (!(bs->spec = strdup(spec))) { logmsg (_("HHCSD003E bind_device strdup() failed for device %4.4X\n"), dev->devnum); free (bs); return 0; /* (failure) */ } /* Create a listening socket */ if (bs->spec[0] == '/') bs->sd = unix_socket (bs->spec); else bs->sd = inet_socket (bs->spec); if (bs->sd == -1) { /* (error message already issued) */ free( bs->spec ); free( bs ); return 0; /* (failure) */ } /* Chain device and bind_struct to each other */ dev->bs = bs; bs->dev = dev; /* Add the new entry to our list of bound devices and create the socket thread that will listen for connections (if it doesn't already exist) */ obtain_lock( &bind_lock ); was_list_empty = IsListEmpty( &bind_head ); InsertListTail( &bind_head, &bs->bind_link ); if ( was_list_empty ) { if ( create_thread( &sysblk.socktid, JOINABLE, socket_thread, NULL, "socket_thread" ) ) { logmsg( _( "HHCSD023E Cannot create socketdevice thread: errno=%d: %s\n" ), errno, strerror( errno ) ); RemoveListEntry( &bs->bind_link ); close_socket(bs->sd); free( bs->spec ); free( bs ); release_lock( &bind_lock ); return 0; /* (failure) */ } } SIGNAL_SOCKDEV_THREAD(); release_lock( &bind_lock ); logmsg (_("HHCSD004I Device %4.4X bound to socket %s\n"), dev->devnum, dev->bs->spec); return 1; /* (success) */ }
VOID LpcExitThread ( PETHREAD Thread ) /*++ Routine Description: This routine is called whenever a thread is exiting and need to cleanup the lpc port for the thread. Arguments: Thread - Supplies the thread being terminated Return Value: None. --*/ { PLPCP_MESSAGE Msg; // // Acquire the mutex that protects the LpcReplyMessage field of // the thread. Zero the field so nobody else tries to process it // when we release the lock. // LpcpAcquireLpcpLock(); if (!IsListEmpty( &Thread->LpcReplyChain )) { RemoveEntryList( &Thread->LpcReplyChain ); } // // Indicate that this thread is exiting // Thread->LpcExitThreadCalled = TRUE; Thread->LpcReplyMessageId = 0; // // If we need to reply to a message then if the thread that we need to reply // to is still around we want to dereference the thread and free the message // Msg = Thread->LpcReplyMessage; if (Msg != NULL) { Thread->LpcReplyMessage = NULL; if (Msg->RepliedToThread != NULL) { ObDereferenceObject( Msg->RepliedToThread ); Msg->RepliedToThread = NULL; } LpcpTrace(( "Cleanup Msg %lx (%d) for Thread %lx allocated\n", Msg, IsListEmpty( &Msg->Entry ), Thread )); LpcpFreeToPortZone( Msg, TRUE ); } // // Free the global lpc lock // LpcpReleaseLpcpLock(); // // And return to our caller // return; }
EFI_STATUS EFIAPI InitializeAttrib ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Command entry point. Parses command line arguments and calls internal function to perform actual action. Arguments: ImageHandle The image handle. SystemTable The system table. Returns: EFI_SUCCESS - Command completed successfully EFI_INVALID_PARAMETER - Command usage error Other value - Unknown error --*/ { UINTN Index; EFI_LIST_ENTRY FileList; EFI_LIST_ENTRY *Link; SHELL_FILE_ARG *Arg; UINT64 Remove; UINT64 Add; EFI_STATUS Status; SHELL_VAR_CHECK_CODE RetCode; CHAR16 *Useful; SHELL_ARG_LIST *Item; SHELL_VAR_CHECK_PACKAGE ChkPck; ZeroMem (&ChkPck, sizeof (SHELL_VAR_CHECK_PACKAGE)); // // We are no being installed as an internal command driver, initialize // as an nshell app and run // EFI_SHELL_APP_INIT (ImageHandle, SystemTable); // // Enable tab key which can pause the output // EnableOutputTabPause(); Status = LibFilterNullArgs (); if (EFI_ERROR (Status)) { return Status; } // // Register our string package with HII and return the handle to it. // If previously registered we will simply receive the handle // EFI_SHELL_STR_INIT (HiiHandle, STRING_ARRAY_NAME, EfiAttribGuid); if (!EFI_PROPER_VERSION (0, 99)) { PrintToken ( STRING_TOKEN (STR_SHELLENV_GNC_COMMAND_NOT_SUPPORT), HiiHandle, L"attrib", EFI_VERSION_0_99 ); Status = EFI_UNSUPPORTED; goto Quit; } RetCode = LibCheckVariables (SI, AttribCheckList, &ChkPck, &Useful); if (VarCheckOk != RetCode) { switch (RetCode) { case VarCheckConflict: PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_FLAG_CONFLICT), HiiHandle, L"attrib", Useful); break; case VarCheckDuplicate: PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_DUP_FLAG), HiiHandle, L"attrib", Useful); break; case VarCheckUnknown: PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiHandle, L"attrib", Useful); break; default: break; } Status = EFI_INVALID_PARAMETER; goto Quit; } // // Out put help. // if (LibCheckVarGetFlag (&ChkPck, L"-b") != NULL) { EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF); } if (LibCheckVarGetFlag (&ChkPck, L"-?") != NULL) { if (IS_OLD_SHELL) { PrintToken (STRING_TOKEN (STR_NO_HELP), HiiHandle); goto Quit; } if (ChkPck.ValueCount > 0 || ChkPck.FlagCount > 2 || (2 == ChkPck.FlagCount && !LibCheckVarGetFlag (&ChkPck, L"-b")) ) { PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiHandle, L"attrib"); Status = EFI_INVALID_PARAMETER; } else { PrintToken (STRING_TOKEN (STR_ATTRIB_VERBOSE_HELP), HiiHandle); Status = EFI_SUCCESS; } goto Quit; } // // Local Variable Initializations // InitializeListHead (&FileList); Link = NULL; Arg = NULL; Remove = 0; Add = 0; // // Parse command line arguments // Item = GetFirstFlag (&ChkPck); for (Index = 0; Index < ChkPck.FlagCount; Index += 1) { if (Item->FlagStr[0] == '-') { // // Attributes to remove // Status = AttribSet (&Item->FlagStr[1], &Remove); if (EFI_ERROR (Status)) { PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"attrib", Item->FlagStr); goto Done; } } else if (Item->FlagStr[0] == '+') { // // Attributes to Add // Status = AttribSet (&Item->FlagStr[1], &Add); if (EFI_ERROR (Status)) { PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"attrib", Item->FlagStr); goto Done; } } else { // // we should never get here // ASSERT (FALSE); } Item = GetNextArg (Item); } Item = GetFirstArg (&ChkPck); for (Index = 0; Index < ChkPck.ValueCount; Index += 1) { Status = ShellFileMetaArg (Item->VarStr, &FileList); if (EFI_ERROR (Status)) { PrintToken (STRING_TOKEN (STR_ATTRIB_CANNOT_OPEN), HiiHandle, L"attrib", Item->VarStr, Status); goto Done; } Item = GetNextArg (Item); } // // if no file is specified, get the whole directory // if (IsListEmpty (&FileList)) { Status = ShellFileMetaArg (L"*", &FileList); if (EFI_ERROR (Status)) { PrintToken (STRING_TOKEN (STR_ATTRIB_CANNOT_OPEN_DIR), HiiHandle, L"attrib", Status); goto Done; } } ShellDelDupFileArg (&FileList); // // Attrib each file // for (Link = FileList.Flink; Link != &FileList; Link = Link->Flink) { // // Break the execution? // if (GetExecutionBreak ()) { goto Done; } Arg = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE); Status = AttribFile (Arg, Remove, Add); } Done: ShellFreeFileList (&FileList); Quit: LibCheckVarFreeVarList (&ChkPck); LibUnInitializeStrings (); return Status; }
NDIS_STATUS HelperPortFlushBSSList( __in PMP_PORT Port ) { MP_RW_LOCK_STATE LockState; PLIST_ENTRY pListEntry; PMP_BSS_ENTRY pBSSEntry = NULL; LONG APRefCount; LIST_ENTRY TempList; PMP_HELPER_PORT HelperPort = MP_GET_HELPPORT(Port); PMP_BSS_LIST pDiscoveredBSSList = &(HelperPort->BSSList); // // Entries that are currently in use (eg for connection) // we cannot flush and instead would put in the temporary queue // InitializeListHead(&TempList); MP_ACQUIRE_WRITE_LOCK(&(HelperPort->BSSList.ListLock), &LockState); while (!IsListEmpty(&(pDiscoveredBSSList->List))) { pListEntry = RemoveHeadList(&(pDiscoveredBSSList->List)); pBSSEntry = CONTAINING_RECORD(pListEntry, MP_BSS_ENTRY, Link); APRefCount = NdisInterlockedDecrement(&(pBSSEntry->RefCount)); if (APRefCount == 0) { NdisAcquireSpinLock(&(pBSSEntry->Lock)); MPASSERT(pBSSEntry->pAssocRequest == NULL); MPASSERT(pBSSEntry->pAssocResponse == NULL); if (pBSSEntry->pDot11BeaconFrame != NULL) { MP_FREE_MEMORY(pBSSEntry->pDot11BeaconFrame); pBSSEntry->pDot11BeaconFrame = NULL; pBSSEntry->BeaconFrameSize = 0; pBSSEntry->MaxBeaconFrameSize= 0; } if (pBSSEntry->pDot11ProbeFrame != NULL) { MP_FREE_MEMORY(pBSSEntry->pDot11ProbeFrame); pBSSEntry->pDot11ProbeFrame = NULL; pBSSEntry->ProbeFrameSize = 0; pBSSEntry->MaxProbeFrameSize= 0; } pBSSEntry->pDot11InfoElemBlob = NULL; pBSSEntry->InfoElemBlobSize = 0; NdisReleaseSpinLock(&(pBSSEntry->Lock)); MP_FREE_MEMORY(pBSSEntry); } else { // Restore refcount and save for adding back to list NdisInterlockedIncrement(&(pBSSEntry->RefCount)); InsertTailList(&TempList, pListEntry); } } pDiscoveredBSSList->NumOfBSSEntries = 0; // // Restore entries that are in use // while (!IsListEmpty(&TempList)) { pListEntry = RemoveHeadList(&TempList); InsertTailList(&(pDiscoveredBSSList->List), pListEntry); pDiscoveredBSSList->NumOfBSSEntries++; } // Since our scan list is flushed, also clear the last scan time HelperPort->ScanContext.LastScanTime = 0; MP_RELEASE_WRITE_LOCK(&(HelperPort->BSSList.ListLock), &LockState); return NDIS_STATUS_SUCCESS;
/* kd> dt ndis!_NDIS_PROTOCOL_BLOCK +0x000 Header : _NDIS_OBJECT_HEADER +0x004 ProtocolDriverContext : Ptr32 Void +0x008 NextProtocol : Ptr32 _NDIS_PROTOCOL_BLOCK +0x00c OpenQueue : Ptr32 _NDIS_OPEN_BLOCK win7 */ BOOLEAN EnumNetCards() { PNDIS_MINIPORT_BLOCK pMiniBlock=NULL; PNDIS_COMMON_OPEN_BLOCK_2k3_early pOpenBlock=NULL; ULONG MiniDriverBlockHeader ; ULONG NetCardType = 0; LIST_ENTRY *pListEntry=NULL; NETCARDS_INFO *pNI=NULL; NTSTATUS status = STATUS_SUCCESS; ULONG uTmp=0; ADAPTER_INFOEX *pAdapterInfoEx = NULL; ADAPTER_INFO AI; WCHAR *p1,*p2; ULONG index=0; UNICODE_STRING uniTmp; DWORD dwVersion=0; PKK_NDIS_PROTOCOL_BLOCK pProtocol = (PKK_NDIS_PROTOCOL_BLOCK)GetProtocolHeader(); dwVersion = GetWindowsVersion(); p1=p2=NULL; //清空列表 if (!IsListEmpty(&g_NetCardsInfoHeader.Next)) { ExInterlockedRemoveHeadList(&g_NetCardsInfoHeader.Next, &g_NetCardsInfoLock); // LockResource(&g_NetCardsInfoLock, TRUE); // pListEntry = RemoveHeadList(&g_NetCardsInfoHeader.Next); // UnlockResource(&g_NetCardsInfoLock); pNI = CONTAINING_RECORD(pListEntry, NETCARDS_INFO, Next); if (NULL==pNI) { DbgBreakPoint(); } RtlFreeAnsiString(&pNI->Name); kfree(pNI); } status = GetAdapterInfo(NULL, &uTmp); if (status==STATUS_BUFFER_TOO_SMALL) { pAdapterInfoEx = kmalloc(uTmp); RtlZeroMemory(pAdapterInfoEx, uTmp); if (NULL== pAdapterInfoEx) { return FALSE; } } status = GetAdapterInfo(pAdapterInfoEx, &uTmp); if (pAdapterInfoEx->uNumber==0) { kprintf("GetAdapterInfo() return pAdapterInfoEx->uNumber==0"); kfree(pAdapterInfoEx); return FALSE; } while (pProtocol) { //search for the nic driver block if (dwVersion==Windows_7||dwVersion==Windows_Vista) { if (((PNDIS_PROTOCOL_BLOCKWin7)pProtocol)->OpenQueue==0) { goto NextBlock; } } else { if (pProtocol->OpenQueue==NULL) { goto NextBlock; } } uTmp=0; //现在使用了protocol链表,所以要防止一个miniport多次使用的情况 if (dwVersion==Windows_Vista||dwVersion==Windows_7) { PNDIS_OPEN_BLOCKWIN7 pOP7 = (PNDIS_OPEN_BLOCKWIN7)((PNDIS_PROTOCOL_BLOCKWin7)pProtocol)->OpenQueue; pMiniBlock = pOP7->MiniportHandle; } else { pMiniBlock = pProtocol->OpenQueue->MiniportHandle; } pListEntry = g_NetCardsInfoHeader.Next.Flink; while(pListEntry&& (pListEntry!=&g_NetCardsInfoHeader.Next)) { pNI = CONTAINING_RECORD(pListEntry, NETCARDS_INFO, Next); if (pNI==NULL) { kprintf("Crash......when checking pMiniBlock is in g_NetCardsInfoHeader already\n"); return FALSE; // DbgBreakPoint(); } if (pNI->pMiniBlock==pMiniBlock) { uTmp = 1; break; } pListEntry = pListEntry->Flink; } if (uTmp==1) { //这个miniport已经使用过了 goto NextBlock; } NetCardType = IsPhysicalMiniport(pMiniBlock); //只取物理网卡 if (NetCardType==0) { goto NextBlock; } pNI = kmalloc(sizeof(NETCARDS_INFO)); RtlZeroMemory(pNI, sizeof(NETCARDS_INFO)); if (NetCardType==1) { SetFlag(pNI->flag, REGULARNETCARD); } if (NetCardType==2) { SetFlag(pNI->flag, WIRELESSNETCARD); } /* p_mini_block->SymbolicLinkName 亦可直接Createfile (p_mini_block->SymbolicLinkName....)发OID_802_3_CURRENT_ADDRESS来查询 */ pNI->pMiniBlock = pMiniBlock; uTmp =0; for (index=0; index<pAdapterInfoEx->uNumber; index++) { p1 = kmalloc(pMiniBlock->SymbolicLinkName.Length+2); RtlZeroMemory(p1, pMiniBlock->SymbolicLinkName.Length+2); RtlCopyMemory(p1, pMiniBlock->SymbolicLinkName.Buffer, pMiniBlock->SymbolicLinkName.Length); AI = pAdapterInfoEx->pAI[index]; p2 = kmalloc(AI.GUID.Length+2); RtlZeroMemory(p2, AI.GUID.Length+2); RtlCopyMemory(p2, AI.GUID.Buffer, AI.GUID.Length); _wcsupr(p1);_wcsupr(p2); if (wcsstr(p1,p2)) { kfree(p1);kfree(p2); uTmp = 1; break; //找到了,已经获取网卡MAC地址 } kfree(p1);kfree(p2); }//end for (index=0; index<pAdapterInfoEx->uNumber; index++) if (uTmp==1) { RtlCopyMemory(pNI->MacAddr, AI.macAddress, sizeof(pNI->MacAddr)); pNI->IPAddr = AI.IPAddr; pNI->GatewayIpAddr = AI.GatewayIpAddr; if (pAdapterInfoEx->pAI[index].bDhcp) { SetFlag(pNI->flag, DHCPENABLE); } ExInterlockedInsertHeadList(&g_NetCardsInfoHeader.Next, &pNI->Next, &g_NetCardsInfoLock); // LockResource(&g_NetCardsInfoLock, TRUE); // InsertHeadList(&g_NetCardsInfoHeader.Next, &pNI->Next); // UnlockResource(&g_NetCardsInfoLock); } else { kfree(pNI); pNI = NULL; goto NextBlock; } // if ((p_mini_block->Flags&ISCONNECTED)) // { // SetFlag(pNI->flag, ISCONNECTED); // } if (AI.status==NdisMediaStateConnected) { SetFlag(pNI->flag, ISCONNECTED); } //HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318} GetNicNameByGUID(&AI.GUID, &uniTmp); RtlUnicodeStringToAnsiString(&pNI->Name, &uniTmp, TRUE); kprintf("\r\n 检举网卡信息如下:\r\nMAC : %02X:%02X:%02X:%02X:%02X:%02X \nIP :0x%x \nflag:0X%X \n网关IP:0x%x \nName: %Z \n\n", pNI->MacAddr[0], pNI->MacAddr[1], pNI->MacAddr[2], pNI->MacAddr[3], pNI->MacAddr[4], pNI->MacAddr[5], (pNI->IPAddr), pNI->flag, (pNI->GatewayIpAddr),&pNI->Name); NextBlock: if (dwVersion==Windows_Vista||dwVersion==Windows_7) { pProtocol = (PKK_NDIS_PROTOCOL_BLOCK )((PNDIS_PROTOCOL_BLOCKWin7)pProtocol)->NextProtocol; } else pProtocol = pProtocol->NextProtocol; } //end while (p_driver_block->NextDriver) //释放上面申请的内容 for (index=0; index<pAdapterInfoEx->uNumber; index++) { kfree(pAdapterInfoEx->pAI[index].GUID.Buffer); } kfree(pAdapterInfoEx); return 1; }
VOID NICHandleRecvInterrupt( IN PFDO_DATA FdoData ) /*++ Routine Description: Interrupt handler for receive processing. Put the received packets into an array and call NICServiceReadIrps. If we run low on RFDs, allocate another one. Assumption: This function is called with the Rcv SPINLOCK held. Arguments: FdoData Pointer to our FdoData Return Value: None --*/ { PMP_RFD pMpRfd = NULL; PHW_RFD pHwRfd = NULL; PMP_RFD PacketArray[NIC_DEF_RFDS]; PMP_RFD PacketFreeArray[NIC_DEF_RFDS]; UINT PacketArrayCount; UINT PacketFreeCount; UINT Index; UINT LoopIndex = 0; UINT LoopCount = NIC_MAX_RFDS / NIC_DEF_RFDS + 1; // avoid staying here too long BOOLEAN bContinue = TRUE; BOOLEAN bAllocNewRfd = FALSE; USHORT PacketStatus; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "---> NICHandleRecvInterrupt\n"); ASSERT(FdoData->nReadyRecv >= NIC_MIN_RFDS); while (LoopIndex++ < LoopCount && bContinue) { PacketArrayCount = 0; PacketFreeCount = 0; // // Process up to the array size RFD's // while (PacketArrayCount < NIC_DEF_RFDS) { if (IsListEmpty(&FdoData->RecvList)) { ASSERT(FdoData->nReadyRecv == 0); bContinue = FALSE; break; } // // Get the next MP_RFD to process // pMpRfd = (PMP_RFD)GetListHeadEntry(&FdoData->RecvList); // // Get the associated HW_RFD // pHwRfd = pMpRfd->HwRfd; // // Is this packet completed? // PacketStatus = NIC_RFD_GET_STATUS(pHwRfd); if (!NIC_RFD_STATUS_COMPLETED(PacketStatus)) { bContinue = FALSE; break; } // // HW specific - check if actual count field has been updated // if (!NIC_RFD_VALID_ACTUALCOUNT(pHwRfd)) { bContinue = FALSE; break; } // // Remove the RFD from the head of the List // RemoveEntryList((PLIST_ENTRY)pMpRfd); FdoData->nReadyRecv--; ASSERT(MP_TEST_FLAG(pMpRfd, fMP_RFD_RECV_READY)); MP_CLEAR_FLAG(pMpRfd, fMP_RFD_RECV_READY); // // A good packet? drop it if not. // if (!NIC_RFD_STATUS_SUCCESS(PacketStatus)) { TraceEvents(TRACE_LEVEL_WARNING, DBG_READ, "Receive failure = %x\n", PacketStatus); NICReturnRFD(FdoData, pMpRfd); continue; } // // Do not receive any packets until a filter has been set // if (!FdoData->PacketFilter) { NICReturnRFD(FdoData, pMpRfd); continue; } // // Do not receive any packets until we are at D0 // if (FdoData->DevicePowerState != PowerDeviceD0) { NICReturnRFD(FdoData, pMpRfd); continue; } pMpRfd->PacketSize = NIC_RFD_GET_PACKET_SIZE(pHwRfd); KeFlushIoBuffers(pMpRfd->Mdl, TRUE, TRUE); // // set the status on the packet, either resources or success // if (FdoData->nReadyRecv >= MIN_NUM_RFD) { MP_SET_FLAG(pMpRfd, fMP_RFD_RECV_PEND); } else { MP_SET_FLAG(pMpRfd, fMP_RFD_RESOURCES); _Analysis_assume_(PacketFreeCount <= PacketArrayCount); PacketFreeArray[PacketFreeCount] = pMpRfd; PacketFreeCount++; // // Reset the RFD shrink count - don't attempt to shrink RFD // FdoData->RfdShrinkCount = 0; // // Remember to allocate a new RFD later // bAllocNewRfd = TRUE; } PacketArray[PacketArrayCount] = pMpRfd; PacketArrayCount++; } // // if we didn't process any receives, just return from here // if (PacketArrayCount == 0) { break; } WdfSpinLockRelease(FdoData->RcvLock); WdfSpinLockAcquire(FdoData->Lock); // // if we have a Recv interrupt and have reported a media disconnect status // time to indicate the new status // if (Disconnected == FdoData->MediaState) { TraceEvents(TRACE_LEVEL_WARNING, DBG_READ, "Media state changed to Connected\n"); MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_NO_CABLE); FdoData->MediaState = Connected; WdfSpinLockRelease(FdoData->Lock); // // Indicate the media event // NICServiceIndicateStatusIrp(FdoData); } else { WdfSpinLockRelease(FdoData->Lock); } NICServiceReadIrps( FdoData, PacketArray, PacketArrayCount); WdfSpinLockAcquire(FdoData->RcvLock); // // Return all the RFDs to the pool. // for (Index = 0; Index < PacketFreeCount; Index++) { // // Get the MP_RFD saved in this packet, in NICAllocRfd // pMpRfd = PacketFreeArray[Index]; ASSERT(MP_TEST_FLAG(pMpRfd, fMP_RFD_RESOURCES)); MP_CLEAR_FLAG(pMpRfd, fMP_RFD_RESOURCES); NICReturnRFD(FdoData, pMpRfd); } } // // If we ran low on RFD's, we need to allocate a new RFD // if (bAllocNewRfd) { // // Allocate one more RFD only if it doesn't exceed the max RFD limit // if (FdoData->CurrNumRfd < FdoData->MaxNumRfd && !FdoData->AllocNewRfd) { NTSTATUS status; FdoData->AllocNewRfd = TRUE; // // Since we are running at DISPATCH_LEVEL, we will queue a workitem // to allocate RFD memory at PASSIVE_LEVEL. Note that // AllocateCommonBuffer and FreeCommonBuffer can be called only at // PASSIVE_LEVEL. // status = PciDrvQueuePassiveLevelCallback(FdoData, NICAllocRfdWorkItem, NULL, NULL); if(!NT_SUCCESS(status)){ FdoData->AllocNewRfd = FALSE; } } } ASSERT(FdoData->nReadyRecv >= NIC_MIN_RFDS); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "<--- NICHandleRecvInterrupt\n"); }
VOID KeUnstackDetachProcess ( IN PRKAPC_STATE ApcState ) /*++ Routine Description: This function detaches a thread from another process' address space and restores previous attach state. Arguments: ApcState - Supplies a pointer to an APC state structure that was returned from a previous call to stack attach process. Return Value: None. --*/ { KIRQL OldIrql; PKPROCESS Process; PKTHREAD Thread; ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); // // Raise IRQL to dispatcher level and lock dispatcher database. // Thread = KeGetCurrentThread(); KiLockDispatcherDatabase(&OldIrql); // // If the APC state has a distinguished process pointer value, then no // attach was performed on the paired call to stack attach process. // if (ApcState->Process != (PRKPROCESS)1) { // // If the current thread is not attached to another process, a kernel // APC is in progress, or either the kernel or user mode APC queues // are not empty, then call bug check. // if ((Thread->ApcStateIndex == 0) || (Thread->ApcState.KernelApcInProgress) || (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) || (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) == FALSE)) { KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT); } // // Unbias current process stack count and check if the process should // be swapped out of memory. // Process = Thread->ApcState.Process; Process->StackCount -= 1; if ((Process->StackCount == 0) && (IsListEmpty(&Process->ThreadListHead) == FALSE)) { Process->State = ProcessInTransition; InsertTailList(&KiProcessOutSwapListHead, &Process->SwapListEntry); KiSwapEvent.Header.SignalState = 1; if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); } } // // Restore APC state and check whether the kernel APC queue contains // an entry. If the kernel APC queue contains an entry then set kernel // APC pending and request a software interrupt at APC_LEVEL. // if (ApcState->Process != NULL) { KiMoveApcState(ApcState, &Thread->ApcState); } else { KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); Thread->SavedApcState.Process = (PKPROCESS)NULL; Thread->ApcStatePointer[0] = &Thread->ApcState; Thread->ApcStatePointer[1] = &Thread->SavedApcState; Thread->ApcStateIndex = 0; } if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) { Thread->ApcState.KernelApcPending = TRUE; KiRequestSoftwareInterrupt(APC_LEVEL); } // // Swap the address space back to the parent process. // KiSwapProcess(Thread->ApcState.Process, Process); } // // Lower IRQL to its previous value and return. // KiUnlockDispatcherDatabase(OldIrql); return; }
LONG KeSetProcess ( IN PRKPROCESS Process, IN KPRIORITY Increment, IN BOOLEAN Wait ) /*++ Routine Description: This function sets the signal state of a proces object to Signaled and attempts to satisfy as many Waits as possible. The previous signal state of the process object is returned as the function value. Arguments: Process - Supplies a pointer to a dispatcher object of type process. Increment - Supplies the priority increment that is to be applied if setting the process causes a Wait to be satisfied. Wait - Supplies a boolean value that signifies whether the call to KeSetProcess will be immediately followed by a call to one of the kernel Wait functions. Return Value: The previous signal state of the process object. --*/ { KIRQL OldIrql; LONG OldState; PRKTHREAD Thread; ASSERT_PROCESS(Process); ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); // // Raise IRQL to dispatcher level and lock dispatcher database. // KiLockDispatcherDatabase(&OldIrql); // // If the previous state of the process object is Not-Signaled and // the wait queue is not empty, then satisfy as many Waits as // possible. // OldState = Process->Header.SignalState; Process->Header.SignalState = 1; if ((OldState == 0) && (!IsListEmpty(&Process->Header.WaitListHead))) { KiWaitTest(Process, Increment); } // // If the value of the Wait argument is TRUE, then return to the // caller with IRQL raised and the dispatcher database locked. Else // release the dispatcher database lock and lower IRQL to its // previous value. // if (Wait) { Thread = KeGetCurrentThread(); Thread->WaitNext = Wait; Thread->WaitIrql = OldIrql; } else { KiUnlockDispatcherDatabase(OldIrql); } // // Return previous signal state of process object. // return OldState; }
VOID KiMoveApcState ( IN PKAPC_STATE Source, OUT PKAPC_STATE Destination ) /*++ Routine Description: This function moves the APC state from the source structure to the destination structure and reinitializes list headers as appropriate. Arguments: Source - Supplies a pointer to the source APC state structure. Destination - Supplies a pointer to the destination APC state structure. Return Value: None. --*/ { PLIST_ENTRY First; PLIST_ENTRY Last; // // Copy the APC state from the source to the destination. // *Destination = *Source; if (IsListEmpty(&Source->ApcListHead[KernelMode]) != FALSE) { InitializeListHead(&Destination->ApcListHead[KernelMode]); } else { First = Source->ApcListHead[KernelMode].Flink; Last = Source->ApcListHead[KernelMode].Blink; Destination->ApcListHead[KernelMode].Flink = First; Destination->ApcListHead[KernelMode].Blink = Last; First->Blink = &Destination->ApcListHead[KernelMode]; Last->Flink = &Destination->ApcListHead[KernelMode]; } if (IsListEmpty(&Source->ApcListHead[UserMode]) != FALSE) { InitializeListHead(&Destination->ApcListHead[UserMode]); } else { First = Source->ApcListHead[UserMode].Flink; Last = Source->ApcListHead[UserMode].Blink; Destination->ApcListHead[UserMode].Flink = First; Destination->ApcListHead[UserMode].Blink = Last; First->Blink = &Destination->ApcListHead[UserMode]; Last->Flink = &Destination->ApcListHead[UserMode]; } return; }
VOID KeDetachProcess ( VOID ) /*++ Routine Description: This function detaches a thread from another process' address space. Arguments: None. Return Value: None. --*/ { KIRQL OldIrql; PKPROCESS Process; PKTHREAD Thread; ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); // // Raise IRQL to dispatcher level and lock dispatcher database. // Thread = KeGetCurrentThread(); KiLockDispatcherDatabase(&OldIrql); // // If the current thread is attached to another process, then detach // it. // if (Thread->ApcStateIndex != 0) { // // Check if a kernel APC is in progress, the kernel APC queue is // not empty, or the user APC queue is not empty. If any of these // conditions are true, then call bug check. // #if DBG if ((Thread->ApcState.KernelApcInProgress) || (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) || (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) == FALSE)) { KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT); } #endif // // Unbias current process stack count and check if the process should // be swapped out of memory. // Process = Thread->ApcState.Process; Process->StackCount -= 1; if ((Process->StackCount == 0) && (IsListEmpty(&Process->ThreadListHead) == FALSE)) { Process->State = ProcessInTransition; InsertTailList(&KiProcessOutSwapListHead, &Process->SwapListEntry); KiSwapEvent.Header.SignalState = 1; if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); } } // // Restore APC state and check whether the kernel APC queue contains // an entry. If the kernel APC queue contains an entry then set kernel // APC pending and request a software interrupt at APC_LEVEL. // KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); Thread->SavedApcState.Process = (PKPROCESS)NULL; Thread->ApcStatePointer[0] = &Thread->ApcState; Thread->ApcStatePointer[1] = &Thread->SavedApcState; Thread->ApcStateIndex = 0; if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) { Thread->ApcState.KernelApcPending = TRUE; KiRequestSoftwareInterrupt(APC_LEVEL); } // // Swap the address space back to the parent process. // KiSwapProcess(Thread->ApcState.Process, Process); } // // Lower IRQL to its previous value and return. // KiUnlockDispatcherDatabase(OldIrql); return; }
DWORD WINAPI WsAsyncThread(IN PWSASYNCCONTEXT Context) { PWSASYNCBLOCK AsyncBlock; PLIST_ENTRY Entry; HANDLE AsyncEvent = Context->AsyncEvent; PLIST_ENTRY ListHead = &Context->AsyncQueue; /* Set the blocking hook */ WSASetBlockingHook((FARPROC)WsAsyncThreadBlockingHook); /* Loop */ while (TRUE) { /* Wait for the event */ WaitForSingleObject(AsyncEvent, INFINITE); /* Get the lock */ WsAsyncLock(); /* Process the queue */ while (ListHead->Flink != ListHead) { /* Remove this entry and get the async block */ Entry = RemoveHeadList(ListHead); AsyncBlock = CONTAINING_RECORD(Entry, WSASYNCBLOCK, AsyncQueue); /* Save the current task handle */ WsAsyncCurrentTaskHandle = AsyncBlock->TaskHandle; /* Release the lock */ WsAsyncUnlock(); /* Check which operation to do */ switch (AsyncBlock->Operation) { /* Get Host by Y */ case WsAsyncGetHostByAddr: case WsAsyncGetHostByName: /* Call the handler */ WsAsyncGetHost(AsyncBlock->TaskHandle, AsyncBlock->Operation, AsyncBlock->GetHost.hWnd, AsyncBlock->GetHost.wMsg, AsyncBlock->GetHost.ByWhat, AsyncBlock->GetHost.Length, AsyncBlock->GetHost.Type, AsyncBlock->GetHost.Buffer, AsyncBlock->GetHost.BufferLength); break; /* Get Proto by Y */ case WsAsyncGetProtoByNumber: case WsAsyncGetProtoByName: /* Call the handler */ WsAsyncGetProto(AsyncBlock->TaskHandle, AsyncBlock->Operation, AsyncBlock->GetProto.hWnd, AsyncBlock->GetProto.wMsg, AsyncBlock->GetHost.ByWhat, AsyncBlock->GetProto.Buffer, AsyncBlock->GetProto.BufferLength); break; /* Get Serv by Y */ case WsAsyncGetServByPort: case WsAsyncGetServByName: /* Call the handler */ WsAsyncGetServ(AsyncBlock->TaskHandle, AsyncBlock->Operation, AsyncBlock->GetServ.hWnd, AsyncBlock->GetServ.wMsg, AsyncBlock->GetServ.ByWhat, AsyncBlock->GetServ.Protocol, AsyncBlock->GetServ.Buffer, AsyncBlock->GetServ.BufferLength); break; /* Termination */ case WsAsyncTerminate: /* Clean up the extra reference */ WSACleanup(); /* Free the context block */ WsAsyncFreeBlock(AsyncBlock); /* Acquire the lock */ WsAsyncLock(); /* Loop the queue and flush it */ while (!IsListEmpty(ListHead)) { Entry = RemoveHeadList(ListHead); AsyncBlock = CONTAINING_RECORD(Entry, WSASYNCBLOCK, AsyncQueue); WsAsyncFreeBlock(AsyncBlock); } /* Release lock */ WsAsyncUnlock(); /* Close the event, free the Context */ CloseHandle(AsyncEvent); HeapFree(WsSockHeap, 0, Context); /* Remove the extra DLL reference and kill us */ FreeLibraryAndExitThread(WsAsyncDllHandle, 0); default: break; } /* Done processing */ WsAsyncCurrentTaskHandle = NULL; /* Free this block, get lock and reloop */ WsAsyncFreeBlock(AsyncBlock); WsAsyncLock(); } /* Release the lock */ WsAsyncUnlock(); } }
/** Function for 'help' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunHelp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CONST COMMAND_LIST *CommandList; CONST COMMAND_LIST *Node; CHAR16 *CommandToGetHelpOn; CHAR16 *SectionToGetHelpOn; CHAR16 *HiiString; BOOLEAN Found; BOOLEAN PrintCommandText; PrintCommandText = TRUE; ProblemParam = NULL; ShellStatus = SHELL_SUCCESS; CommandToGetHelpOn = NULL; SectionToGetHelpOn = NULL; Found = FALSE; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); // ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { return Status; } Status = CommandInit(); // ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { return Status; } // // parse the command line // Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"help", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { // ASSERT(FALSE); return Status; } } else { // // Check for conflicting parameters. // if (ShellCommandLineGetFlag(Package, L"-usage") && ShellCommandLineGetFlag(Package, L"-section") && (ShellCommandLineGetFlag(Package, L"-verbose") || ShellCommandLineGetFlag(Package, L"-v"))) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel3HiiHandle, L"help"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel3HiiHandle, L"help"); ShellStatus = SHELL_INVALID_PARAMETER; } else { // // Get the command name we are getting help on // // ASSERT(CommandToGetHelpOn == NULL); StrnCatGrow(&CommandToGetHelpOn, NULL, ShellCommandLineGetRawValue(Package, 1), 0); if (CommandToGetHelpOn == NULL && ShellCommandLineGetFlag(Package, L"-?")) { // // If we dont have a command and we got a simple -? // we are looking for help on help command. // StrnCatGrow(&CommandToGetHelpOn, NULL, L"help", 0); } if (CommandToGetHelpOn == NULL) { StrnCatGrow(&CommandToGetHelpOn, NULL, L"*", 0); // Print(L"if NULL then *\n"); // ASSERT(SectionToGetHelpOn == NULL); StrnCatGrow(&SectionToGetHelpOn, NULL, L"NAME", 0); } else { PrintCommandText = FALSE; // ASSERT(SectionToGetHelpOn == NULL); // // Get the section name for the given command name // if (ShellCommandLineGetFlag(Package, L"-section")) { StrnCatGrow(&SectionToGetHelpOn, NULL, ShellCommandLineGetValue(Package, L"-section"), 0); } else if (ShellCommandLineGetFlag(Package, L"-usage")) { StrnCatGrow(&SectionToGetHelpOn, NULL, L"NAME,SYNOPSIS", 0); } else if (ShellCommandLineGetFlag(Package, L"-verbose") || ShellCommandLineGetFlag(Package, L"-v")) { } else { // // The output of help <command> will display NAME, SYNOPSIS, OPTIONS, DESCRIPTION, and EXAMPLES sections. // StrnCatGrow (&SectionToGetHelpOn, NULL, L"NAME,SYNOPSIS,OPTIONS,DESCRIPTION,EXAMPLES", 0); } } if (gUnicodeCollation->StriColl(gUnicodeCollation, CommandToGetHelpOn, L"special") == 0) { // // we need info on the special characters // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_SC_HEADER), gShellLevel3HiiHandle); HiiString = HiiGetString(gShellLevel3HiiHandle, STRING_TOKEN(STR_HELP_SC_DATA), NULL); ShellPrintEx(-1, -1, L"%s", HiiString); FreePool(HiiString); Found = TRUE; } else { CommandList = ShellCommandGetCommandList(TRUE); // ASSERT(CommandList != NULL); for ( Node = (COMMAND_LIST*)GetFirstNode(&CommandList->Link) ; CommandList != NULL && !IsListEmpty(&CommandList->Link) && !IsNull(&CommandList->Link, &Node->Link) ; Node = (COMMAND_LIST*)GetNextNode(&CommandList->Link, &Node->Link) ) { // // Checking execution break flag when print multiple command help information. // if (ShellGetExecutionBreakFlag ()) { break; } if ((gUnicodeCollation->MetaiMatch(gUnicodeCollation, Node->CommandString, CommandToGetHelpOn)) || (gEfiShellProtocol->GetAlias(CommandToGetHelpOn, NULL) != NULL && (gUnicodeCollation->MetaiMatch(gUnicodeCollation, Node->CommandString, (CHAR16*)(gEfiShellProtocol->GetAlias(CommandToGetHelpOn, NULL)))))) { // Print(L"found node %s\n", Node->CommandString); // // We have a command to look for help on. // Status = ShellPrintHelp(Node->CommandString, SectionToGetHelpOn, PrintCommandText); if (Status == EFI_DEVICE_ERROR) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_INV), gShellLevel3HiiHandle, Node->CommandString); } else if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_NF), gShellLevel3HiiHandle, Node->CommandString); } else { Found = TRUE; } } } // // now try to match against the dynamic command list and print help // Status = PrintDynamicCommandHelp (CommandToGetHelpOn, SectionToGetHelpOn, PrintCommandText); if (!EFI_ERROR(Status)) { Found = TRUE; } // // Search the .man file for Shell applications (Shell external commands). // if (!Found) { Status = ShellPrintHelp(CommandToGetHelpOn, SectionToGetHelpOn, FALSE); if (Status == EFI_DEVICE_ERROR) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_INV), gShellLevel3HiiHandle, CommandToGetHelpOn); } else if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_NF), gShellLevel3HiiHandle, CommandToGetHelpOn); } else { Found = TRUE; } } } if (!Found) { ShellStatus = SHELL_NOT_FOUND; } // // free the command line package // ShellCommandLineFreeVarList (Package); } } if (CommandToGetHelpOn != NULL && StrCmp(CommandToGetHelpOn, L"*") == 0) { // // If '*' then the command entered was 'Help' without qualifiers, This footer // provides additional info on help switches // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_FOOTER), gShellLevel3HiiHandle); } if (CommandToGetHelpOn != NULL) { FreePool(CommandToGetHelpOn); } if (SectionToGetHelpOn != NULL) { FreePool(SectionToGetHelpOn); } return (ShellStatus); }
NTSTATUS DokanFindStreams(PFILE_STREAM_INFORMATION StreamInfo, PDOKAN_FILE_INFO FileInfo, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance, PULONG RemainingLength) { PDOKAN_OPEN_INFO openInfo = (PDOKAN_OPEN_INFO)(UINT_PTR)FileInfo->DokanContext; NTSTATUS status = STATUS_SUCCESS; if (!DokanInstance->DokanOperations->FindStreams) { return STATUS_NOT_IMPLEMENTED; } if (openInfo->StreamListHead == NULL) { openInfo->StreamListHead = malloc(sizeof(LIST_ENTRY)); if (openInfo->StreamListHead != NULL) { InitializeListHead(openInfo->StreamListHead); } else { status = STATUS_NO_MEMORY; } } if (status == STATUS_SUCCESS && IsListEmpty(openInfo->StreamListHead)) { status = DokanInstance->DokanOperations->FindStreams( EventContext->Operation.File.FileName, DokanFillFindStreamData, FileInfo); } if (status == STATUS_SUCCESS) { PLIST_ENTRY listHead, entry; ULONG entrySize; listHead = openInfo->StreamListHead; entrySize = 0; for (entry = listHead->Flink; entry != listHead; entry = entry->Flink) { PDOKAN_FIND_STREAM_DATA find = CONTAINING_RECORD(entry, DOKAN_FIND_STREAM_DATA, ListEntry); ULONG nextEntryOffset = entrySize; ULONG streamNameLength = (ULONG)wcslen(find->FindStreamData.cStreamName) * sizeof(WCHAR); entrySize = sizeof(FILE_STREAM_INFORMATION) + streamNameLength; // Must be align on a 8-byte boundary. entrySize = QuadAlign(entrySize); if (*RemainingLength < entrySize) { status = STATUS_BUFFER_OVERFLOW; break; } // Not the first entry, set the offset before filling the new entry if (nextEntryOffset > 0) { StreamInfo->NextEntryOffset = nextEntryOffset; StreamInfo = (PFILE_STREAM_INFORMATION)((LPBYTE)StreamInfo + StreamInfo->NextEntryOffset); } // Fill the new entry StreamInfo->StreamNameLength = streamNameLength; memcpy(StreamInfo->StreamName, find->FindStreamData.cStreamName, streamNameLength); StreamInfo->StreamSize = find->FindStreamData.StreamSize; StreamInfo->StreamAllocationSize = find->FindStreamData.StreamSize; StreamInfo->NextEntryOffset = 0; ALIGN_ALLOCATION_SIZE(&StreamInfo->StreamAllocationSize); *RemainingLength -= entrySize; } if (status != STATUS_BUFFER_OVERFLOW) { ClearFindStreamData(openInfo->StreamListHead); } } else { ClearFindStreamData(openInfo->StreamListHead); } return status; }
static NTSTATUS VfatDismountVolume( PVFAT_IRP_CONTEXT IrpContext) { PDEVICE_EXTENSION DeviceExt; PLIST_ENTRY NextEntry; PVFATFCB Fcb; PFILE_OBJECT FileObject; ULONG eocMark; NTSTATUS Status; DPRINT("VfatDismountVolume(%p)\n", IrpContext); DeviceExt = IrpContext->DeviceExt; FileObject = IrpContext->FileObject; /* We HAVE to be locked. Windows also allows dismount with no lock * but we're here mainly for 1st stage, so KISS */ if (!(DeviceExt->Flags & VCB_VOLUME_LOCKED)) { return STATUS_ACCESS_DENIED; } /* Race condition? */ if (DeviceExt->Flags & VCB_DISMOUNT_PENDING) { return STATUS_VOLUME_DISMOUNTED; } /* Notify we'll dismount. Pass that point there's no reason we fail */ FsRtlNotifyVolumeEvent(IrpContext->Stack->FileObject, FSRTL_VOLUME_DISMOUNT); ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE); if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY) { /* Set clean shutdown bit */ Status = GetNextCluster(DeviceExt, 1, &eocMark); if (NT_SUCCESS(Status)) { eocMark |= DeviceExt->CleanShutBitMask; if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark))) DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY; } } /* Flush volume & files */ VfatFlushVolume(DeviceExt, (PVFATFCB)FileObject->FsContext); /* Rebrowse the FCB in order to free them now */ while (!IsListEmpty(&DeviceExt->FcbListHead)) { NextEntry = RemoveHeadList(&DeviceExt->FcbListHead); Fcb = CONTAINING_RECORD(NextEntry, VFATFCB, FcbListEntry); vfatDestroyFCB(Fcb); } /* Mark we're being dismounted */ DeviceExt->Flags |= VCB_DISMOUNT_PENDING; #ifndef ENABLE_SWAPOUT IrpContext->DeviceObject->Vpb->Flags &= ~VPB_MOUNTED; #endif ExReleaseResourceLite(&DeviceExt->FatResource); /* Release a few resources and quit, we're done */ ExDeleteResourceLite(&DeviceExt->DirResource); ExDeleteResourceLite(&DeviceExt->FatResource); ObDereferenceObject(DeviceExt->FATFileObject); return STATUS_SUCCESS; }
VOID KiAttachProcess ( IN PRKTHREAD Thread, IN PKPROCESS Process, IN KIRQL OldIrql, OUT PRKAPC_STATE SavedApcState ) /*++ Routine Description: This function attaches a thread to a target process' address space. N.B. The dispatcher database lock must be held when this routine is called. Arguments: Thread - Supplies a pointer to a dispatcher object of type thread. Process - Supplies a pointer to a dispatcher object of type process. OldIrql - Supplies the previous IRQL. SavedApcState - Supplies a pointer to the APC state structure that receives the saved APC state. Return Value: None. --*/ { PRKTHREAD OutThread; KAFFINITY Processor; PLIST_ENTRY NextEntry; KIRQL HighIrql; ASSERT(Process != Thread->ApcState.Process); // // Bias the stack count of the target process to signify that a // thread exists in that process with a stack that is resident. // Process->StackCount += 1; // // Save current APC state and initialize a new APC state. // KiMoveApcState(&Thread->ApcState, SavedApcState); InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]); InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]); Thread->ApcState.Process = Process; Thread->ApcState.KernelApcInProgress = FALSE; Thread->ApcState.KernelApcPending = FALSE; Thread->ApcState.UserApcPending = FALSE; if (SavedApcState == &Thread->SavedApcState) { Thread->ApcStatePointer[0] = &Thread->SavedApcState; Thread->ApcStatePointer[1] = &Thread->ApcState; Thread->ApcStateIndex = 1; } // // If the target process is in memory, then immediately enter the // new address space by loading a new Directory Table Base. Otherwise, // insert the current thread in the target process ready list, inswap // the target process if necessary, select a new thread to run on the // the current processor and context switch to the new thread. // if (Process->State == ProcessInMemory) { // // It is possible that the process is in memory, but there exist // threads in the process ready list. This can happen when memory // management forces a process attach. // NextEntry = Process->ReadyListHead.Flink; while (NextEntry != &Process->ReadyListHead) { OutThread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry); RemoveEntryList(NextEntry); OutThread->ProcessReadyQueue = FALSE; KiReadyThread(OutThread); NextEntry = Process->ReadyListHead.Flink; } KiSwapProcess(Process, SavedApcState->Process); KiUnlockDispatcherDatabase(OldIrql); } else { Thread->State = Ready; Thread->ProcessReadyQueue = TRUE; InsertTailList(&Process->ReadyListHead, &Thread->WaitListEntry); if (Process->State == ProcessOutOfMemory) { Process->State = ProcessInTransition; InsertTailList(&KiProcessInSwapListHead, &Process->SwapListEntry); KiSwapEvent.Header.SignalState = 1; if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); } } // // Clear the active processor bit in the previous process and // set active processor bit in the process being attached to. // #if !defined(NT_UP) KiLockContextSwap(&HighIrql); Processor = KeGetCurrentPrcb()->SetMember; SavedApcState->Process->ActiveProcessors &= ~Processor; Process->ActiveProcessors |= Processor; #if defined(_ALPHA_) Process->RunOnProcessors |= Processor; #endif KiUnlockContextSwap(HighIrql); #endif Thread->WaitIrql = OldIrql; KiSwapThread(); } return; }
////////////////////////////////////////////////////////////////////////// //取出pendding的IRP,并完成,用户层异步得到通知 VOID AskUserWorker(PDEVICE_OBJECT DeviceObject, PVOID pContext) { PIO_WORKITEM pWorkItem = NULL; PASKUserWorkItemContext pAskContext =NULL; PIRP Irp=NULL; PLIST_ENTRY pListEntry=NULL; NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION irpStack; PVOID ioBuf; ULONG inBufLength, outBufLength; PFIREWALL_ASKUSER pFireAskUser=NULL; KIRQL CIrql,CIrql2; CIrql=CIrql2=0; CIrql = KeGetCurrentIrql(); pAskContext = (PASKUserWorkItemContext)pContext; do { if (pAskContext==NULL) { break; } while(!IsListEmpty(&g_AskUserConnectListHeader)) { //find a pendding irp 2 ask user decision pListEntry = ExInterlockedRemoveHeadList(&g_AskUserConnectListHeader, &g_AskUserConnectListLock); Irp = CONTAINING_RECORD(pListEntry, IRP, Tail.Overlay.ListEntry); break; } if (Irp==NULL) { break; } irpStack = IoGetCurrentIrpStackLocation(Irp); ioBuf = Irp->AssociatedIrp.SystemBuffer; inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; pFireAskUser = (PFIREWALL_ASKUSER)ioBuf; //把DST、SRC IP,PORT带上去,后面再带下来 //let ring3 know what the port is asking for permission *pFireAskUser = *(PFIREWALL_ASKUSER)pAskContext->pContext; Status = STATUS_SUCCESS; Irp->IoStatus.Status = Status; Irp->IoStatus.Information = sizeof(FIREWALL_ASKUSER); IoCompleteRequest(Irp, IO_NO_INCREMENT); } while (0); if (pAskContext) { IoFreeWorkItem(pAskContext->pWorkItem); kfree(pAskContext->pContext); kfree(pAskContext); } if (KeGetCurrentIrql()>CIrql) { KeLowerIrql(CIrql); } if (KeGetCurrentIrql()<CIrql) { KeRaiseIrql(CIrql, &CIrql2); } }
static NTSTATUS NTAPI ConSrvTermReadStream(IN OUT PTERMINAL This, /**/IN PUNICODE_STRING ExeName /**/OPTIONAL/**/,/**/ IN BOOLEAN Unicode, /**PWCHAR Buffer,**/ OUT PVOID Buffer, IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl, IN ULONG NumCharsToRead, OUT PULONG NumCharsRead OPTIONAL) { PFRONTEND FrontEnd = This->Data; PCONSRV_CONSOLE Console = FrontEnd->Console; PCONSOLE_INPUT_BUFFER InputBuffer = &Console->InputBuffer; // STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait. NTSTATUS Status = STATUS_PENDING; PLIST_ENTRY CurrentEntry; ConsoleInput *Input; ULONG i; /* Validity checks */ // ASSERT(Console == InputBuffer->Header.Console); ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0)); /* We haven't read anything (yet) */ i = ReadControl->nInitialChars; if (InputBuffer->Mode & ENABLE_LINE_INPUT) { /* COOKED mode, call the line discipline */ if (Console->LineBuffer == NULL) { /* Starting a new line */ Console->LineMaxSize = max(256, NumCharsToRead); Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR)); if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY; Console->LinePos = Console->LineSize = ReadControl->nInitialChars; Console->LineComplete = Console->LineUpPressed = FALSE; Console->LineInsertToggle = Console->InsertMode; Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask; /* * Pre-filling the buffer is only allowed in the Unicode API, * so we don't need to worry about ANSI <-> Unicode conversion. */ memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR)); if (Console->LineSize == Console->LineMaxSize) { Console->LineComplete = TRUE; Console->LinePos = 0; } } /* If we don't have a complete line yet, process the pending input */ while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents)) { /* Remove input event from queue */ CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); if (IsListEmpty(&InputBuffer->InputEvents)) { ResetEvent(InputBuffer->ActiveEvent); } Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); /* Only pay attention to key down */ if (Input->InputEvent.EventType == KEY_EVENT && Input->InputEvent.Event.KeyEvent.bKeyDown) { LineInputKeyDown(Console, ExeName, &Input->InputEvent.Event.KeyEvent); ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState; } ConsoleFreeHeap(Input); } /* Check if we have a complete line to read from */ if (Console->LineComplete) { while (i < NumCharsToRead && Console->LinePos != Console->LineSize) { WCHAR Char = Console->LineBuffer[Console->LinePos++]; if (Unicode) { ((PWCHAR)Buffer)[i] = Char; } else { ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char); } ++i; } if (Console->LinePos == Console->LineSize) { /* Entire line has been read */ ConsoleFreeHeap(Console->LineBuffer); Console->LineBuffer = NULL; } Status = STATUS_SUCCESS; } } else { /* RAW mode */ /* Character input */ while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents)) { /* Remove input event from queue */ CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); if (IsListEmpty(&InputBuffer->InputEvents)) { ResetEvent(InputBuffer->ActiveEvent); } Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); /* Only pay attention to valid characters, on key down */ if (Input->InputEvent.EventType == KEY_EVENT && Input->InputEvent.Event.KeyEvent.bKeyDown && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0') { WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar; if (Unicode) { ((PWCHAR)Buffer)[i] = Char; } else { ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char); } ++i; /* Did read something */ Status = STATUS_SUCCESS; } ConsoleFreeHeap(Input); } } // FIXME: Only set if Status == STATUS_SUCCESS ??? if (NumCharsRead) *NumCharsRead = i; return Status; }
VOID NICReturnRFD( IN PFDO_DATA FdoData, IN PMP_RFD pMpRfd ) /*++ Routine Description: Recycle a RFD and put it back onto the receive list Assumption: This function is called with the Rcv SPINLOCK held. Arguments: FdoData Pointer to our FdoData pMpRfd Pointer to the RFD Return Value: None --*/ { PMP_RFD pLastMpRfd; PHW_RFD pHwRfd = pMpRfd->HwRfd; ASSERT(pMpRfd->Flags == 0); MP_SET_FLAG(pMpRfd, fMP_RFD_RECV_READY); // // HW_SPECIFIC_START // pHwRfd->RfdCbHeader.CbStatus = 0; pHwRfd->RfdActualCount = 0; pHwRfd->RfdCbHeader.CbCommand = (RFD_EL_BIT); pHwRfd->RfdCbHeader.CbLinkPointer = DRIVER_NULL; // // Append this RFD to the RFD chain if (!IsListEmpty(&FdoData->RecvList)) { pLastMpRfd = (PMP_RFD)GetListTailEntry(&FdoData->RecvList); // Link it onto the end of the chain dynamically pHwRfd = pLastMpRfd->HwRfd; pHwRfd->RfdCbHeader.CbLinkPointer = pMpRfd->HwRfdPhys; pHwRfd->RfdCbHeader.CbCommand = 0; } // // HW_SPECIFIC_END // // // The processing on this RFD is done, so put it back on the tail of // our list // InsertTailList(&FdoData->RecvList, (PLIST_ENTRY)pMpRfd); FdoData->nReadyRecv++; ASSERT(FdoData->nReadyRecv <= FdoData->CurrNumRfd); }
/////////////////////////////////////////////////////////////////////////////// // // OsrProcessQueuedRequests // // This interface checks the current state of the read and write // queues, and starts requests on the device if either are not // busy. // // INPUTS: // // devExt - Pointer to device extension of device to start // // OUTPUTS: // // None. // // RETURNS: // // None. // // IRQL: // // // NOTES: // /////////////////////////////////////////////////////////////////////////////// VOID OsrProcessQueuedRequests(IN OUT POSR_DEVICE_EXT devExt) { PVOID entry; PIRP irp; KIRQL oldIrql; // // See if there's something to start on the WRITE queue // KeAcquireSpinLock(&devExt->WriteQueueLock, &oldIrql); while ( !devExt->CurrentWriteIrp && !IsListEmpty(&devExt->WriteQueue) ) { entry = RemoveHeadList(&devExt->WriteQueue); irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry); #if DBG DbgPrint("OsrProcessQueued: IRP removed from WRITE queue = 0x%0x\n",irp); #endif // // If this IRP is cancelled, cancel it now, without // initiating it on the device // if (irp->Cancel) { #if DBG DbgPrint("OsrProcessQueued: CANCEL flag set in READ IRP removed from queue 0x%0x\n",irp); #endif irp->IoStatus.Status = STATUS_CANCELLED; irp->IoStatus.Information = 0; // // Complete the request now // IoCompleteRequest(irp, IO_NO_INCREMENT); } else { // // Since we do not cancel in-progress requests // on this device, we will reset the cancel // routine in the IRP to NULL. // IoSetCancelRoutine(irp, NULL); // // Make this IRP the current write IRP, and // start the request on the device. This routine // sets devExt->CurrentWriteIrp // OsrStartWriteIrp(devExt->FunctionalDeviceObject, irp); } } // while (!devExt->CurrentWriteIrp && // !IsListEmpty(devExt->WriteQueue) ) // // Drop the lock // KeReleaseSpinLock(&devExt->WriteQueueLock, oldIrql); // // See if there's something to start on the READ queue // KeAcquireSpinLock(&devExt->ReadQueueLock, &oldIrql); while ( !devExt->CurrentReadIrp && !IsListEmpty(&devExt->ReadQueue) ) { entry = RemoveHeadList(&devExt->ReadQueue); irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry); #if DBG DbgPrint("OsrProcessQueued: IRP removed from READ queue = 0x%0x\n",irp); #endif // // If this IRP is cancelled, cancel it now, without // initiating it on the device // if (irp->Cancel) { #if DBG DbgPrint("OsrProcessQueued: CANCEL flag set in READ IRP removed from queue 0x%0x\n",irp); #endif irp->IoStatus.Status = STATUS_CANCELLED; irp->IoStatus.Information = 0; // // Complete the request now // IoCompleteRequest(irp, IO_NO_INCREMENT); } else { // // Since we do not cancel in-progress requests // on this device, we will reset the cancel // routine in the IRP to NULL. // IoSetCancelRoutine(irp, NULL); // // Make this IRP the current read IRP, and // start the request on the device. This routine // sets devExt->CurrentReadIrp // OsrStartReadIrp(devExt->FunctionalDeviceObject, irp); } } // while (!devExt->CurrentReadIrp && // !IsListEmpty(devExt->ReadQueue) ) // // Drop the lock // KeReleaseSpinLock(&devExt->ReadQueueLock, oldIrql); }
NTSTATUS NICStartRecv( IN PFDO_DATA FdoData ) /*++ Routine Description: Start the receive unit if it's not in a ready state Assumption: This function is called with the Rcv SPINLOCK held. Arguments: FdoData Pointer to our FdoData Return Value: NT Status code --*/ { PMP_RFD pMpRfd; NTSTATUS status; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "---> NICStartRecv\n"); // // If the receiver is ready, then don't try to restart. // if (NIC_IS_RECV_READY(FdoData)) { TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "Receive unit already active\n"); return STATUS_SUCCESS; } TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "Re-start receive unit...\n"); ASSERT(!IsListEmpty(&FdoData->RecvList)); // // Get the MP_RFD head // pMpRfd = (PMP_RFD)GetListHeadEntry(&FdoData->RecvList); // // If more packets are received, clean up RFD chain again // if (NIC_RFD_GET_STATUS(pMpRfd->HwRfd)) { NICHandleRecvInterrupt(FdoData); ASSERT(!IsListEmpty(&FdoData->RecvList)); // // Get the new MP_RFD head // pMpRfd = (PMP_RFD)GetListHeadEntry(&FdoData->RecvList); } // // Wait for the SCB to clear before we set the general pointer // if (!WaitScb(FdoData)) { status = STATUS_DEVICE_DATA_ERROR; goto exit; } if (FdoData->DevicePowerState > PowerDeviceD0) { status = STATUS_DEVICE_DATA_ERROR; goto exit; } // // Set the SCB General Pointer to point the current Rfd // FdoData->CSRAddress->ScbGeneralPointer = pMpRfd->HwRfdPhys; // // Issue the SCB RU start command // status = D100IssueScbCommand(FdoData, SCB_RUC_START, FALSE); if (status == STATUS_SUCCESS) { // wait for the command to be accepted if (!WaitScb(FdoData)) { status = STATUS_DEVICE_DATA_ERROR; } } exit: TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "<--- NICStartRecv, Status=%x\n", status); return status; }
NTSTATUS ReleaseTimeoutPendingIrp( __in PDokanDCB Dcb ) { KIRQL oldIrql; PLIST_ENTRY thisEntry, nextEntry, listHead; PIRP_ENTRY irpEntry; LARGE_INTEGER tickCount; LIST_ENTRY completeList; PIRP irp; DDbgPrint("==> ReleaseTimeoutPendingIRP\n"); InitializeListHead(&completeList); ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); KeAcquireSpinLock(&Dcb->PendingIrp.ListLock, &oldIrql); // when IRP queue is empty, there is nothing to do if (IsListEmpty(&Dcb->PendingIrp.ListHead)) { KeReleaseSpinLock(&Dcb->PendingIrp.ListLock, oldIrql); DDbgPrint(" IrpQueue is Empty\n"); return STATUS_SUCCESS; } KeQueryTickCount(&tickCount); // search timeout IRP through pending IRP list listHead = &Dcb->PendingIrp.ListHead; for (thisEntry = listHead->Flink; thisEntry != listHead; thisEntry = nextEntry) { nextEntry = thisEntry->Flink; irpEntry = CONTAINING_RECORD(thisEntry, IRP_ENTRY, ListEntry); // this IRP is NOT timeout yet if (tickCount.QuadPart < irpEntry->TickCount.QuadPart) { break; } RemoveEntryList(thisEntry); DDbgPrint(" timeout Irp #%X\n", irpEntry->SerialNumber); irp = irpEntry->Irp; if (irp == NULL) { // this IRP has already been canceled ASSERT(irpEntry->CancelRoutineFreeMemory == FALSE); DokanFreeIrpEntry(irpEntry); continue; } // this IRP is not canceled yet if (IoSetCancelRoutine(irp, NULL) == NULL) { // Cancel routine will run as soon as we release the lock InitializeListHead(&irpEntry->ListEntry); irpEntry->CancelRoutineFreeMemory = TRUE; continue; } // IrpEntry is saved here for CancelRoutine // Clear it to prevent to be completed by CancelRoutine twice irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_IRP_ENTRY] = NULL; InsertTailList(&completeList, &irpEntry->ListEntry); } if (IsListEmpty(&Dcb->PendingIrp.ListHead)) { KeClearEvent(&Dcb->PendingIrp.NotEmpty); } KeReleaseSpinLock(&Dcb->PendingIrp.ListLock, oldIrql); while (!IsListEmpty(&completeList)) { listHead = RemoveHeadList(&completeList); irpEntry = CONTAINING_RECORD(listHead, IRP_ENTRY, ListEntry); irp = irpEntry->Irp; DokanCompleteIrpRequest(irp, STATUS_INSUFFICIENT_RESOURCES, 0); DokanFreeIrpEntry(irpEntry); } DDbgPrint("<== ReleaseTimeoutPendingIRP\n"); return STATUS_SUCCESS; }
// Read an environment BOOL environment_open(Cfg_Environment *env,char *name,BOOL first,APTR prog) { struct OpenEnvironmentData *opendata; BOOL success; short progress=1; // Free volatile memory ClearMemHandle(env->volatile_memory); // Initialise open structure if (!(opendata=AllocMemH(env->volatile_memory,sizeof(struct OpenEnvironmentData)))) return 0; opendata->memory=env->desktop_memory; opendata->volatile_memory=env->volatile_memory; opendata->flags=OEDF_ALL; // Initialise progress SetProgressWindowTags(prog,PW_FileCount,14,PW_FileNum,1,TAG_END); // Read environment if ((success=OpenEnvironment((name)?name:env->path,opendata))) { // Check stack setting and increase if too low if (opendata->env.default_stack < STACK_DEFAULT) opendata->env.default_stack = STACK_DEFAULT; // Copy things back to the environment CopyMem((char *)&opendata->env,(char *)env->env,sizeof(CFG_ENVR)); strcpy(env->toolbar_path,opendata->toolbar_path); strcpy(env->menu_path,opendata->menu_path); strcpy(env->user_menu_path,opendata->user_menu_path); strcpy(env->scripts_path,opendata->scripts_path); strcpy(env->hotkeys_path,opendata->hotkeys_path); // Get maximum filename length // we have to do this before the listers are opened GUI->def_filename_length=environment->env->settings.max_filename; if (GUI->def_filename_length<FILENAME_LEN) GUI->def_filename_length=FILENAME_LEN; else if (GUI->def_filename_length>107) GUI->def_filename_length=107; } // Successful? if (success || first) { ButtonBankNode *button; OpenListerNode *lister; // Bump progress main_bump_progress(prog,progress++,0); // Store new environment path if (name) strcpy(env->path,name); // Bump progress main_bump_progress(prog,progress++,0); // Get new toolbar FreeToolBar(GUI->toolbar); GUI->toolbar=OpenToolBar(0,env->toolbar_path); // Bump progress main_bump_progress(prog,progress++,0); // Free lister menu, get new one CloseButtonBank(GUI->lister_menu); if ((GUI->lister_menu=OpenButtonBank(env->menu_path))) { // Check if it needs conversion if (!(GUI->lister_menu->window.flags&BTNWF_FIX_MENU)) { // Convert it to new format ConvertStartMenu(GUI->lister_menu); GUI->lister_menu->window.flags|=BTNWF_FIX_MENU; } } // Bump progress main_bump_progress(prog,progress++,0); // Free user menu, get new one CloseButtonBank(GUI->user_menu); GUI->user_menu=OpenButtonBank(env->user_menu_path); // Bump progress main_bump_progress(prog,progress++,0); // Free scripts, get new set CloseButtonBank(GUI->scripts); GUI->scripts=OpenButtonBank(env->scripts_path); // Bump progress main_bump_progress(prog,progress++,0); // Free hotkeys, get new ones send_main_reset_cmd(CONFIG_CHANGE_HOTKEYS,0,0); // Go through buttons to open for (button=(ButtonBankNode *)opendata->buttons.mlh_Head; button->node.ln_Succ;) { ButtonBankNode *next=(ButtonBankNode *)button->node.ln_Succ; Buttons *but; // Create button bank from this node if ((but=buttons_new(button->node.ln_Name,0,&button->pos,0,button->flags|BUTTONF_FAIL))) { // Set icon position but->icon_pos_x=button->icon_pos_x; but->icon_pos_y=button->icon_pos_y; } // Free this node, get next Remove((struct Node *)button); FreeMemH(button->node.ln_Name); FreeMemH(button); button=next; } // Bump progress main_bump_progress(prog,progress++,0); // Go through StartMenus to open for (button=(ButtonBankNode *)opendata->startmenus.mlh_Head; button->node.ln_Succ;) { ButtonBankNode *next=(ButtonBankNode *)button->node.ln_Succ; // Create new start menu start_new(button->node.ln_Name,0,0,button->pos.Left,button->pos.Top); // Free this node, get next Remove((struct Node *)button); FreeMemH(button->node.ln_Name); FreeMemH(button); button=next; } // Bump progress main_bump_progress(prog,progress++,0); // Go through listers to open for (lister=(OpenListerNode *)opendata->listers.mlh_Head; lister->node.ln_Succ;) { OpenListerNode *next=(OpenListerNode *)lister->node.ln_Succ; // Create lister from this node if (lister->lister) lister_new((Cfg_Lister *)lister->lister); // Free this node, get next Remove((struct Node *)lister); FreeMemH(lister); lister=next; } // Bump progress main_bump_progress(prog,progress++,0); // Free existing desktop list env_free_desktop(&env->desktop); // Copy new desktop into list if (!(IsListEmpty((struct List *)&opendata->desktop))) { env->desktop=opendata->desktop; env->desktop.mlh_TailPred->mln_Succ=(struct MinNode *)&env->desktop.mlh_Tail; env->desktop.mlh_Head->mln_Pred=(struct MinNode *)&env->desktop.mlh_Head; } // Free existing path list env_free_desktop(&env->path_list); // Copy new pathlist into list if (!(IsListEmpty((struct List *)&opendata->pathlist))) { env->path_list=opendata->pathlist; env->path_list.mlh_TailPred->mln_Succ=(struct MinNode *)&env->path_list.mlh_Tail; env->path_list.mlh_Head->mln_Pred=(struct MinNode *)&env->path_list.mlh_Head; } // Free existing sound list env_free_desktop(&env->sound_list); // Copy new sound list into list if (!(IsListEmpty((struct List *)&opendata->soundlist))) { env->sound_list=opendata->soundlist; env->sound_list.mlh_TailPred->mln_Succ=(struct MinNode *)&env->sound_list.mlh_Tail; env->sound_list.mlh_Head->mln_Pred=(struct MinNode *)&env->sound_list.mlh_Head; } // Bump progress main_bump_progress(prog,progress++,0); // Update priority IPC_Command(&main_ipc, IPC_PRIORITY, env->env->settings.pri_main[1], (APTR)env->env->settings.pri_main[0], 0,0); // Fix lister priorities lister_fix_priority(0); // Bump progress main_bump_progress(prog,progress++,0); } // Failed, free temp lists else { env_free_desktop(&opendata->desktop); env_free_desktop(&opendata->pathlist); env_free_desktop(&opendata->soundlist); env_free_desktop(&opendata->startmenus); env_free_desktop(&opendata->buttons); env_free_desktop(&opendata->listers); } // Free open data structure FreeMemH(opendata); // Bump progress main_bump_progress(prog,progress,0); // Build the user menu (needed even if there is none) display_build_user_menu(); // Initialise progress SetProgressWindowTags(prog,PW_FileCount,1,PW_FileNum,1,TAG_END); // Set library flag for 'Move AppIcons to Tools Menu' SetLibraryFlags((env->env->display_options&DISPOPTF_SHIFT_APPICONS)?LIBDF_REDIRECT_TOOLS:0,LIBDF_REDIRECT_TOOLS); // Set library flag for borderless icons SetLibraryFlags((env->env->desktop_flags&DESKTOPF_NO_BORDERS)?LIBDF_BORDERS_OFF:0,LIBDF_BORDERS_OFF); // No icon caching? SetLibraryFlags((env->env->desktop_flags&DESKTOPF_NO_CACHE)?LIBDF_NO_CACHING:0,LIBDF_NO_CACHING); // Set NewIcons flags SetNewIconsFlags(env->env->env_NewIconsFlags,env->env->env_NewIconsPrecision); // No custom drag? SetLibraryFlags((env->env->desktop_flags&DESKTOPF_NO_CUSTOMDRAG)?LIBDF_NO_CUSTOM_DRAG:0,LIBDF_NO_CUSTOM_DRAG); // Thin borders? SetLibraryFlags((env->env->display_options&DISPOPTF_THIN_BORDERS)?LIBDF_THIN_BORDERS:0,LIBDF_THIN_BORDERS); // Update pathlist environment variable env_update_pathlist(); // Set popup delay SetPopUpDelay(env->env->settings.popup_delay); // Fix MUFS library env_fix_mufs(); // Assign themes path env_fix_themes(); // Initialise sound events InitSoundEvents(TRUE); return success; }
VOID DispatchDirectoryInformation( HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { PEVENT_INFORMATION eventInfo; DOKAN_FILE_INFO fileInfo; PDOKAN_OPEN_INFO openInfo; int status = 0; ULONG fileInfoClass = EventContext->Directory.FileInformationClass; ULONG sizeOfEventInfo = sizeof(EVENT_INFORMATION) - 8 + EventContext->Directory.BufferLength; BOOLEAN patternCheck = TRUE; CheckFileName(EventContext->Directory.DirectoryName); eventInfo = DispatchCommon( EventContext, sizeOfEventInfo, DokanInstance, &fileInfo, &openInfo); // check whether this is handled FileInfoClass if (fileInfoClass != FileDirectoryInformation && fileInfoClass != FileFullDirectoryInformation && fileInfoClass != FileNamesInformation && fileInfoClass != FileIdBothDirectoryInformation && fileInfoClass != FileBothDirectoryInformation) { logw(L"not suported type %d", fileInfoClass); // send directory info to driver eventInfo->BufferLength = 0; eventInfo->Status = STATUS_NOT_IMPLEMENTED; SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); return; } // IMPORTANT!! // this buffer length is fixed in MatchFiles funciton eventInfo->BufferLength = EventContext->Directory.BufferLength; if (openInfo->DirListHead == NULL) { openInfo->DirListHead = (PLIST_ENTRY)malloc(sizeof(LIST_ENTRY)); InitializeListHead(openInfo->DirListHead); } if (EventContext->Directory.FileIndex == 0) { ClearFindData(openInfo->DirListHead); } if (IsListEmpty(openInfo->DirListHead)) { logw(L"###FindFiles %04d", openInfo->EventId); // if user defined FindFilesWithPattern if (DokanInstance->DokanOperations->FindFilesWithPattern) { LPCWSTR pattern = L"*"; // if search pattern is specified if (EventContext->Directory.SearchPatternLength != 0) { pattern = (PWCHAR)((SIZE_T)&EventContext->Directory.SearchPatternBase[0] + (SIZE_T)EventContext->Directory.SearchPatternOffset); } patternCheck = FALSE; // do not recheck pattern later in MatchFiles status = DokanInstance->DokanOperations->FindFilesWithPattern( EventContext->Directory.DirectoryName, pattern, DokanFillFileData, &fileInfo); } else if (DokanInstance->DokanOperations->FindFiles) { patternCheck = TRUE; // do pattern check later in MachFiles // call FileSystem specifeid callback routine status = DokanInstance->DokanOperations->FindFiles( EventContext->Directory.DirectoryName, DokanFillFileData, &fileInfo); } else { status = -1; } } if (status < 0) { if (EventContext->Directory.FileIndex == 0) { logw(L" STATUS_NO_SUCH_FILE"); eventInfo->Status = STATUS_NO_SUCH_FILE; } else { logw(L" STATUS_NO_MORE_FILES"); eventInfo->Status = STATUS_NO_MORE_FILES; } eventInfo->BufferLength = 0; eventInfo->Directory.Index = EventContext->Directory.FileIndex; // free all of list entries ClearFindData(openInfo->DirListHead); } else { LONG index; eventInfo->Status = STATUS_SUCCESS; logw(L"index from %d", EventContext->Directory.FileIndex); // extract entries that match search pattern from FindFiles result index = MatchFiles(EventContext, eventInfo, openInfo->DirListHead, patternCheck); // there is no matched file if (index <0) { if (EventContext->Directory.FileIndex == 0) { logw(L" STATUS_NO_SUCH_FILE"); eventInfo->Status = STATUS_NO_SUCH_FILE; } else { logw(L" STATUS_NO_MORE_FILES"); eventInfo->Status = STATUS_NO_MORE_FILES; } eventInfo->BufferLength = 0; eventInfo->Directory.Index = EventContext->Directory.FileIndex; ClearFindData(openInfo->DirListHead); } else { logw(L"index to %d", index); eventInfo->Directory.Index = index; } } // information for FileSystem openInfo->UserContext = fileInfo.Context; // send directory information to driver SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); return; }
VOID NotificationLoop( __in PIRP_LIST PendingIrp, __in PIRP_LIST NotifyEvent ) { PDRIVER_EVENT_CONTEXT driverEventContext; PLIST_ENTRY listHead; PIRP_ENTRY irpEntry; LIST_ENTRY completeList; NTSTATUS status; KIRQL irpIrql; KIRQL notifyIrql; PIRP irp; ULONG eventLen; ULONG bufferLen; PVOID buffer; //DDbgPrint("=> NotificationLoop\n"); InitializeListHead(&completeList); ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); KeAcquireSpinLock(&PendingIrp->ListLock, &irpIrql); KeAcquireSpinLock(&NotifyEvent->ListLock, ¬ifyIrql); while (!IsListEmpty(&PendingIrp->ListHead) && !IsListEmpty(&NotifyEvent->ListHead)) { listHead = RemoveHeadList(&NotifyEvent->ListHead); driverEventContext = CONTAINING_RECORD( listHead, DRIVER_EVENT_CONTEXT, ListEntry); listHead = RemoveHeadList(&PendingIrp->ListHead); irpEntry = CONTAINING_RECORD(listHead, IRP_ENTRY, ListEntry); eventLen = driverEventContext->EventContext.Length; // ensure this eventIrp is not cancelled irp = irpEntry->Irp; if (irp == NULL) { // this IRP has already been canceled ASSERT(irpEntry->CancelRoutineFreeMemory == FALSE); DokanFreeIrpEntry(irpEntry); // push back InsertTailList(&NotifyEvent->ListHead, &driverEventContext->ListEntry); continue; } if (IoSetCancelRoutine(irp, NULL) == NULL) { // Cancel routine will run as soon as we release the lock InitializeListHead(&irpEntry->ListEntry); irpEntry->CancelRoutineFreeMemory = TRUE; // push back InsertTailList(&NotifyEvent->ListHead, &driverEventContext->ListEntry); continue; } // available size that is used for event notification bufferLen = irpEntry->IrpSp->Parameters.DeviceIoControl.OutputBufferLength; // buffer that is used to inform Event buffer = irp->AssociatedIrp.SystemBuffer; // buffer is not specified or short of length if (bufferLen == 0 || buffer == NULL || bufferLen < eventLen) { DDbgPrint("EventNotice : STATUS_INSUFFICIENT_RESOURCES\n"); DDbgPrint(" bufferLen: %d, eventLen: %d\n", bufferLen, eventLen); // push back InsertTailList(&NotifyEvent->ListHead, &driverEventContext->ListEntry); // marks as STATUS_INSUFFICIENT_RESOURCES irpEntry->SerialNumber = 0; } else { // let's copy EVENT_CONTEXT RtlCopyMemory(buffer, &driverEventContext->EventContext, eventLen); // save event length irpEntry->SerialNumber = eventLen; if (driverEventContext->Completed) { KeSetEvent(driverEventContext->Completed, IO_NO_INCREMENT, FALSE); } ExFreePool(driverEventContext); } InsertTailList(&completeList, &irpEntry->ListEntry); } KeClearEvent(&NotifyEvent->NotEmpty); KeClearEvent(&PendingIrp->NotEmpty); KeReleaseSpinLock(&NotifyEvent->ListLock, notifyIrql); KeReleaseSpinLock(&PendingIrp->ListLock, irpIrql); while (!IsListEmpty(&completeList)) { listHead = RemoveHeadList(&completeList); irpEntry = CONTAINING_RECORD(listHead, IRP_ENTRY, ListEntry); irp = irpEntry->Irp; if (irpEntry->SerialNumber == 0) { irp->IoStatus.Information = 0; irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; } else { irp->IoStatus.Information = irpEntry->SerialNumber; irp->IoStatus.Status = STATUS_SUCCESS; } DokanFreeIrpEntry(irpEntry); IoCompleteRequest(irp, IO_NO_INCREMENT); } //DDbgPrint("<= NotificationLoop\n"); }
BOOLEAN CacheInitializeDrive(UCHAR DriveNumber) { PCACHE_BLOCK NextCacheBlock; GEOMETRY DriveGeometry; // If we already have a cache for this drive then // by all means lets keep it, unless it is a removable // drive, in which case we'll invalidate the cache if ((CacheManagerInitialized) && (DriveNumber == CacheManagerDrive.DriveNumber) && (DriveNumber >= 0x80) && (!CacheManagerDataInvalid)) { return TRUE; } CacheManagerDataInvalid = FALSE; // // If we have already been initialized then free // the old data // if (CacheManagerInitialized) { CacheManagerInitialized = FALSE; TRACE("CacheBlockCount: %d\n", CacheBlockCount); TRACE("CacheSizeLimit: %d\n", CacheSizeLimit); TRACE("CacheSizeCurrent: %d\n", CacheSizeCurrent); // // Loop through and free the cache blocks // while (!IsListEmpty(&CacheManagerDrive.CacheBlockHead)) { NextCacheBlock = CONTAINING_RECORD(RemoveHeadList(&CacheManagerDrive.CacheBlockHead), CACHE_BLOCK, ListEntry); FrLdrTempFree(NextCacheBlock->BlockData, TAG_CACHE_DATA); FrLdrTempFree(NextCacheBlock, TAG_CACHE_BLOCK); } } // Initialize the structure RtlZeroMemory(&CacheManagerDrive, sizeof(CACHE_DRIVE)); InitializeListHead(&CacheManagerDrive.CacheBlockHead); CacheManagerDrive.DriveNumber = DriveNumber; if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry)) { return FALSE; } CacheManagerDrive.BytesPerSector = DriveGeometry.BytesPerSector; // Get the number of sectors in each cache block CacheManagerDrive.BlockSize = MachDiskGetCacheableBlockCount(DriveNumber); CacheBlockCount = 0; CacheSizeLimit = TotalPagesInLookupTable / 8 * MM_PAGE_SIZE; CacheSizeCurrent = 0; if (CacheSizeLimit > TEMP_HEAP_SIZE - (128 * 1024)) { CacheSizeLimit = TEMP_HEAP_SIZE - (128 * 1024); } CacheManagerInitialized = TRUE; TRACE("Initializing BIOS drive 0x%x.\n", DriveNumber); TRACE("BytesPerSector: %d.\n", CacheManagerDrive.BytesPerSector); TRACE("BlockSize: %d.\n", CacheManagerDrive.BlockSize); TRACE("CacheSizeLimit: %d.\n", CacheSizeLimit); return TRUE; }
/** Stops a device controller or a bus controller. The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). As a result, much of the error checking on the parameters to Stop() has been moved into this common boot service. It is legal to call Stop() from other locations, but the following calling restrictions must be followed, or the system behavior will not be deterministic. 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this same driver's Start() function. 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid EFI_HANDLE. In addition, all of these handles must have been created in this driver's Start() function, and the Start() function must have called OpenProtocol() on ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. @param[in] ControllerHandle A handle to the device being stopped. The handle must support a bus specific I/O protocol for the driver to use to stop the device. @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL if NumberOfChildren is 0. @retval EFI_SUCCESS The device was stopped. @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. **/ EFI_STATUS EFIAPI I2cHostDriverStop ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer ) { EFI_STATUS Status; I2C_HOST_CONTEXT *I2cHostContext; EFI_I2C_HOST_PROTOCOL *I2cHost; EFI_TPL TplPrevious; TplPrevious = EfiGetCurrentTpl (); if (TplPrevious > TPL_I2C_SYNC) { DEBUG ((EFI_D_ERROR, "I2cHost: TPL %d is too high in Stop.\n", TplPrevious)); return EFI_DEVICE_ERROR; } Status = gBS->OpenProtocol ( Controller, &gEfiI2cHostProtocolGuid, (VOID **) &I2cHost, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } I2cHostContext = I2C_HOST_CONTEXT_FROM_PROTOCOL (I2cHost); // // Raise TPL for critical section // TplPrevious = gBS->RaiseTPL (TPL_I2C_SYNC); // // If there is pending request or pending bus configuration, do not stop // Status = EFI_DEVICE_ERROR; if (( !I2cHostContext->I2cBusConfigurationManagementPending ) && IsListEmpty (&I2cHostContext->RequestList)) { // // Remove the I2C host protocol // Status = gBS->UninstallMultipleProtocolInterfaces ( Controller, &gEfiI2cHostProtocolGuid, I2cHost, NULL ); } // // Leave critical section // gBS->RestoreTPL (TplPrevious); if (!EFI_ERROR (Status)) { gBS->CloseProtocol ( Controller, &gEfiI2cBusConfigurationManagementProtocolGuid, This->DriverBindingHandle, Controller ); // // Release I2c Host resources // if (I2cHostContext->I2cBusConfigurationEvent != NULL) { gBS->CloseEvent (I2cHostContext->I2cBusConfigurationEvent); I2cHostContext->I2cBusConfigurationEvent = NULL; } if (I2cHostContext->I2cEvent != NULL) { gBS->CloseEvent (I2cHostContext->I2cEvent); I2cHostContext->I2cEvent = NULL; } FreePool (I2cHostContext); } // // Return the stop status // return Status; }
/** Function for 'cp' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunCp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; UINTN ParamCount; UINTN LoopCounter; EFI_SHELL_FILE_INFO *FileList; BOOLEAN SilentMode; BOOLEAN RecursiveMode; CONST CHAR16 *Cwd; ProblemParam = NULL; ShellStatus = SHELL_SUCCESS; ParamCount = 0; FileList = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { // // check for "-?" // if (ShellCommandLineGetFlag(Package, L"-?")) { ASSERT(FALSE); } // // Initialize SilentMode and RecursiveMode // if (gEfiShellProtocol->BatchIsActive()) { SilentMode = TRUE; } else { SilentMode = ShellCommandLineGetFlag(Package, L"-q"); } RecursiveMode = ShellCommandLineGetFlag(Package, L"-r"); switch (ParamCount = ShellCommandLineGetCount(Package)) { case 0: case 1: // // we have insufficient parameters // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle); ShellStatus = SHELL_INVALID_PARAMETER; break; case 2: // // must have valid CWD for single parameter... // Cwd = ShellGetCurrentDir(NULL); if (Cwd == NULL){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellLevel2HiiHandle); ShellStatus = SHELL_INVALID_PARAMETER; } else { Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, 1), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); if (FileList == NULL || IsListEmpty(&FileList->Link) || EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1)); ShellStatus = SHELL_NOT_FOUND; } else { ShellStatus = ProcessValidateAndCopyFiles(FileList, Cwd, SilentMode, RecursiveMode); } } break; default: // // Make a big list of all the files... // for (ParamCount--, LoopCounter = 1 ; LoopCounter < ParamCount && ShellStatus == SHELL_SUCCESS ; LoopCounter++) { if (ShellGetExecutionBreakFlag()) { break; } Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, LoopCounter), EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ, &FileList); if (EFI_ERROR(Status) || FileList == NULL || IsListEmpty(&FileList->Link)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, LoopCounter)); ShellStatus = SHELL_NOT_FOUND; } } if (ShellStatus != SHELL_SUCCESS) { Status = ShellCloseFileMetaArg(&FileList); } else { // // now copy them all... // if (FileList != NULL && !IsListEmpty(&FileList->Link)) { ShellStatus = ProcessValidateAndCopyFiles(FileList, PathCleanUpDirectories((CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount)), SilentMode, RecursiveMode); Status = ShellCloseFileMetaArg(&FileList); if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_FILE), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, ParamCount), ShellStatus|MAX_BIT); ShellStatus = SHELL_ACCESS_DENIED; } } } break; } // switch on parameter count if (FileList != NULL) { ShellCloseFileMetaArg(&FileList); } // // free the command line package // ShellCommandLineFreeVarList (Package); } if (ShellGetExecutionBreakFlag()) { return (SHELL_ABORTED); } return (ShellStatus); }
NTSTATUS FatCommonPnp ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp ) /*++ Routine Description: This is the common routine for doing PnP operations called by both the fsd and fsp threads Arguments: Irp - Supplies the Irp to process Return Value: NTSTATUS - The return status for the operation --*/ { NTSTATUS Status; PIO_STACK_LOCATION IrpSp; PVOLUME_DEVICE_OBJECT OurDeviceObject; PVCB Vcb; // // Get the current Irp stack location. // IrpSp = IoGetCurrentIrpStackLocation( Irp ); // // Find our Vcb. This is tricky since we have no file object in the Irp. // OurDeviceObject = (PVOLUME_DEVICE_OBJECT) IrpSp->DeviceObject; // // Make sure this device object really is big enough to be a volume device // object. If it isn't, we need to get out before we try to reference some // field that takes us past the end of an ordinary device object. // if (OurDeviceObject->DeviceObject.Size != sizeof(VOLUME_DEVICE_OBJECT) || NodeType( &OurDeviceObject->Vcb ) != FAT_NTC_VCB) { // // We were called with something we don't understand. // Status = STATUS_INVALID_PARAMETER; FatCompleteRequest( IrpContext, Irp, Status ); return Status; } // // Force everything to wait. // SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT); Vcb = &OurDeviceObject->Vcb; #ifdef __ND_FAT_SECONDARY__ if( ((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->Secondary && ( ((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->NetdiskEnableMode == NETDISK_SECONDARY || ((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->NetdiskEnableMode == NETDISK_SECONDARY2PRIMARY ) ) { PSECONDARY Secondary = ((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->Secondary; Status = STATUS_SUCCESS; Secondary_Reference( Secondary ); switch ( IrpSp->MinorFunction ) { case IRP_MN_QUERY_REMOVE_DEVICE: { DebugTrace2( 0, Dbg, ("FatCommonPnp: IRP_MN_QUERY_REMOVE_DEVICE NetdiskEnableMode = %d\n", ((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->NetdiskEnableMode) ); ExAcquireFastMutex( &Secondary->FastMutex ); if (!Secondary->TryCloseActive) { Secondary->TryCloseActive = TRUE; ExReleaseFastMutex( &Secondary->FastMutex ); Secondary_Reference( Secondary ); //FatDebugTraceLevel |= DEBUG_TRACE_CLOSE; SecondaryTryClose( IrpContext, Secondary ); //FatDebugTraceLevel &= ~DEBUG_TRACE_CLOSE; } else { ExReleaseFastMutex( &Secondary->FastMutex ); } if(Vcb->SecondaryOpenFileCount) { LARGE_INTEGER interval; // Wait all files closed interval.QuadPart = (1 * HZ); //delay 1 seconds KeDelayExecutionThread(KernelMode, FALSE, &interval); } #if 0 if (Vcb->SecondaryOpenFileCount) { LONG ccbCount; PLIST_ENTRY ccbListEntry; PVOID restartKey; PFCB fcb; ExAcquireFastMutex( &Secondary->RecoveryCcbQMutex ); for (ccbCount = 0, ccbListEntry = Secondary->RecoveryCcbQueue.Flink; ccbListEntry != &Secondary->RecoveryCcbQueue; ccbListEntry = ccbListEntry->Flink, ccbCount++); ExReleaseFastMutex( &Secondary->RecoveryCcbQMutex ); ASSERT( !IsListEmpty(&Secondary->RecoveryCcbQueue) ); ASSERT( ccbCount == Vcb->SecondaryOpenFileCount ); DebugTrace2( 0, Dbg, ("IRP_MN_QUERY_REMOVE_DEVICE: Vcb->SecondaryCloseCount = %d, Vcb->CloseCount = %d, ccbCount = %d\n", Vcb->SecondaryOpenFileCount, Vcb->OpenCount, ccbCount) ); restartKey = NULL; fcb = NdFatGetNextFcbTableEntry( &Secondary->VolDo->Vcb, &restartKey ); ASSERT( fcb != NULL || !IsListEmpty(&Secondary->DeletedFcbQueue) ); Status = STATUS_UNSUCCESSFUL; } #endif break; } case IRP_MN_REMOVE_DEVICE: { PVOID restartKey; PFCB fcb; DebugTrace2( 0, Dbg, ("FatCommonPnp: IRP_MN_REMOVE_DEVICE NetdiskEnableMode = %d\n", ((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->NetdiskEnableMode) ); #if 0 restartKey = NULL; fcb = NdFatGetNextFcbTableEntry( &Secondary->VolDo->Vcb, &restartKey ); ASSERT( fcb == NULL && IsListEmpty(&Secondary->DeletedFcbQueue) ); #endif if(Vcb->SecondaryOpenFileCount) { ASSERT( NDFAT_BUG ); Status = STATUS_UNSUCCESSFUL; } break; } default: { DebugTrace2( 0, Dbg, ("FatCommonPnp: IrpSp-MinorFunction = %d NetdiskEnableMode = %d\n", IrpSp->MinorFunction, ((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->NetdiskEnableMode) ); if(IrpSp->FileObject && IS_SECONDARY_FILEOBJECT(IrpSp->FileObject)) { ASSERT( FALSE ); Status = STATUS_UNSUCCESSFUL; } break; } } Secondary_Dereference( Secondary ); if (!NT_SUCCESS(Status)) { FatCompleteRequest( NULL, Irp, Status ); return Status; } } #endif // // Case on the minor code. // switch ( IrpSp->MinorFunction ) { case IRP_MN_QUERY_REMOVE_DEVICE: Status = FatPnpQueryRemove( IrpContext, Irp, Vcb ); break; case IRP_MN_SURPRISE_REMOVAL: Status = FatPnpSurpriseRemove( IrpContext, Irp, Vcb ); break; case IRP_MN_REMOVE_DEVICE: Status = FatPnpRemove( IrpContext, Irp, Vcb ); break; case IRP_MN_CANCEL_REMOVE_DEVICE: Status = FatPnpCancelRemove( IrpContext, Irp, Vcb ); break; default: // // Just pass the IRP on. As we do not need to be in the // way on return, ellide ourselves out of the stack. // IoSkipCurrentIrpStackLocation( Irp ); Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); // // Cleanup our Irp Context. The driver has completed the Irp. // FatCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); break; } return Status; }
NTSTATUS NTAPI USBPORT_SyncResetPipeAndClearStall(IN PDEVICE_OBJECT FdoDevice, IN PIRP Irp, IN PURB Urb) { PUSBPORT_DEVICE_HANDLE DeviceHandle; PUSBPORT_PIPE_HANDLE PipeHandle; PUSBPORT_ENDPOINT Endpoint; ULONG EndpointState; NTSTATUS Status; DPRINT_URB("USBPORT_SyncResetPipeAndClearStall: ... \n"); ASSERT(Urb->UrbHeader.UsbdDeviceHandle); ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST)); ASSERT(Urb->UrbPipeRequest.PipeHandle); DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle; PipeHandle = Urb->UrbPipeRequest.PipeHandle; if (!USBPORT_ValidatePipeHandle(DeviceHandle, PipeHandle)) { return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_INVALID_PIPE_HANDLE); } if (PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE) { return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS); } Endpoint = PipeHandle->Endpoint; InterlockedIncrement(&DeviceHandle->DeviceHandleLock); if (Endpoint->EndpointProperties.TransferType != USBPORT_TRANSFER_TYPE_ISOCHRONOUS) { Urb->UrbHeader.UsbdFlags |= USBD_FLAG_NOT_ISO_TRANSFER; Status = USBPORT_ClearStall(FdoDevice, Irp, Urb); } else { Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS); } if (NT_SUCCESS(Status)) { Status = USBPORT_ResetPipe(FdoDevice, Irp, Urb); if (Endpoint->EndpointProperties.TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) { while (TRUE) { KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql); EndpointState = USBPORT_GetEndpointState(Endpoint); if (EndpointState == USBPORT_ENDPOINT_PAUSED && IsListEmpty(&Endpoint->TransferList)) { USBPORT_SetEndpointState(Endpoint, USBPORT_ENDPOINT_ACTIVE); } KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql); if (EndpointState == USBPORT_ENDPOINT_ACTIVE) { break; } USBPORT_Wait(FdoDevice, 1); } } } InterlockedDecrement(&DeviceHandle->DeviceHandleLock); return Status; }