VOID FxWorkItem::WaitForSignal( VOID ) { LARGE_INTEGER timeOut; NTSTATUS status; ASSERT(Mx::MxGetCurrentIrql() == PASSIVE_LEVEL); timeOut.QuadPart = WDF_REL_TIMEOUT_IN_SEC(60); do { status = m_WorkItemCompleted.EnterCRAndWaitAndLeave(&timeOut.QuadPart); if (status == STATUS_TIMEOUT) { DbgPrint("Thread 0x%p is waiting on WDFWORKITEM 0x%p\n", Mx::GetCurrentEThread(), GetHandle()); } else { ASSERT(NT_SUCCESS(status)); break; } } WHILE(TRUE); ASSERT(NT_SUCCESS(status)); return; }
int ft_opera_handler(char *str) { int k; char **tb; INIT(int, i, ft_is_opera(str)); if (i >= 0) return (ft_truc2(str, i)); i = red_is(str); IF_(i >= 0); tb = malloc(sizeof(char *) * (COUNTC(str, '>') + COUNTC(str, '<') + 2)); INIT(int, j, ft_getcharpos(str, g_rc[i], 0)); DBA(k, 0, tb[k++], ft_strsub(str, 0, j)); str = str + j; WHILE(i >= 0 && j >= 0); j = ft_getcharpos(str + ((str[1] == g_rc[i]) ? 2 : 1), g_rc[i], 0); IF_(j >= 0); tb[k++] = ft_strsub(str, 0, j + ((str[1] == g_rc[i]) ? 2 : 1)); str = str + ((j > 0) ? j : 1) + ((str[1] == g_rc[i]) ? 2 : 1); i = red_is(str); ELSE(tb[k++] = ft_strdup(str)); ENDWHILE; tb[k] = NULL; return (ft_truc(tb)); ENDIF; return (-2); }
int main() { Init(); CustomKernel mandelbrot; MODULE_INT_START(mandelbrot) MOUDLE_INPUT_FLOAT(x) MOUDLE_INPUT_FLOAT(y) MODULE_INPUT_INT(maxItt) MODULE_MAIN FLOAT(a = 0.0f) FLOAT(b = 0.0f) INT(i = 0) INT(j = 0) WHILE(i < maxItt) BEGIN IF( a * a + b * b > 4) BEGIN STATEMENT(j = 1) BREAK END FLOAT(aTemp = a) STATEMENT(a = a * a - b * b + x) STATEMENT(b = 2 * aTemp * b + y) STATEMENT(i++) END MODULE_RETURN(i) MODULE_END CustomKernel mandelbrotRun; KERNEL_START(mandelbrotRun) KERNEL_INPUT_INT(itt) INCLUDE(mandelbrot) KERNEL_MAIN INT(val) FLOAT(x = (MYCOORD.x - 0.5) * 4) FLOAT(y = (MYCOORD.y - 0.5) * 4) CALL(val, mandelbrot, x, y, itt) KERNEL_OUTPUT(1.5 / float(val)) KERNEL_END DeviceVector dVOut(1024, 1024); HostVector hVOut; mandelbrotRun.Input(500); mandelbrotRun.Output(dVOut); mandelbrotRun.Execute(); hVOut = dVOut; ImageProcessing::SaveImageFile("mandelbrot.bmp", hVOut); getchar(); return 0; }
VOID NICFreeQueuedSendPackets( IN PFDO_DATA FdoData ) /*++ Routine Description: Free and complete the pended sends on SendQueueHead Assumption: This function is called with the Send SPINLOCK held. Arguments: FdoData Pointer to our FdoData Return Value: None --*/ { WDFREQUEST request; NTSTATUS status; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "--> NICFreeQueuedSendPackets\n"); do { status = WdfIoQueueRetrieveNextRequest( FdoData->PendingWriteQueue, &request ); if(!NT_SUCCESS(status) ) { if(STATUS_NO_MORE_ENTRIES != status){ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "WdfIoQueueRetrieveNextRequest failed %x\n", status); } break; } FdoData->nWaitSend--; WdfSpinLockRelease(FdoData->SendLock); WdfRequestCompleteWithInformation(request, status, 0); WdfSpinLockAcquire(FdoData->SendLock); } WHILE (TRUE); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE, "<-- NICFreeQueuedSendPackets\n"); }
static int write_c_str_list( // WRITE VARIABLE LIST OF STRINGS, LIST char **pstr ) // - pointer to list { int retn; // - return: 0 ==> ok GUESS :: NO_ERRS WHILE( *pstr != NULL ) retn = write_c_str( *pstr++ ); QUITIF( retn != 0 ) :: NO_ERRS ENDWHILE ENDGUESS return( retn ); }
setsym() { INT relflg; INT symval, symflg; SYMSLAVE *symptr; SYMPTR symp; TXTHDR txthdr; fsym=getfile(symfil,1); txtmap.ufd=fsym; IF read(fsym, txthdr, TXTHDRSIZ)==TXTHDRSIZ THEN magic=txthdr[0]; IF magic!=0411 ANDF magic!=0410 ANDF magic!=0407 ANDF magic!=0405 THEN magic=0; ELSE symnum=txthdr[4]/SYMTABSIZ; txtsiz=txthdr[1]; datsiz=txthdr[2]; symbas=txtsiz+datsiz; txtmap.b1=0; txtmap.e1=(magic==0407?symbas:txtsiz); txtmap.f1 = TXTHDRSIZ; txtmap.b2=datbas=(magic==0410?round(txtsiz,TXTRNDSIZ):0); txtmap.e2=txtmap.b2+(magic==0407?symbas:datsiz); txtmap.f2 = TXTHDRSIZ+(magic==0407?0:txtmap.e1); entrypt=txthdr[5]; relflg=txthdr[7]; IF relflg!=1 THEN symbas =<< 1; FI symbas += TXTHDRSIZ; /* set up symvec */ symvec=sbrk(shorten((1+symnum))*sizeof (SYMSLAVE)); IF (symptr=symvec)==-1 THEN printf("%s\n",BADNAM); symptr=symvec=sbrk(sizeof (SYMSLAVE)); ELSE symset(); WHILE (symp=symget()) ANDF errflg==0 DO symval=symp->symv; symflg=symp->symf; symptr->valslave=symval; symptr->typslave=SYMTYPE(symflg); symptr++; OD FI symptr->typslave=ESYM; FI FI IF magic==0 THEN txtmap.e1=maxfile; FI }
NTSTATUS MPIssueScbPoMgmtCommand( IN PFDO_DATA FdoData, IN PCSR_FILTER_STRUC pNewFilter, IN BOOLEAN WaitForScb ) { NTSTATUS status = STATUS_UNSUCCESSFUL; UNREFERENCED_PARAMETER( pNewFilter ); UNREFERENCED_PARAMETER( WaitForScb ); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "--> MPIssueScbPoMgmtCommand\n"); do { // Set up SCB to issue this command status = MPSetUpFilterCB(FdoData); if (status != STATUS_SUCCESS) { break; } // Submit the configure command to the chip, and wait for // it to complete. FdoData->CSRAddress->ScbGeneralPointer = FdoData->NonTxCmdBlockPhys; status = D100SubmitCommandBlockAndWait(FdoData); if(status != STATUS_SUCCESS) { status = STATUS_DEVICE_DATA_ERROR; break; } } WHILE (FALSE); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "<-- MPIssueScbPoMgmtCommand %x\n", status); return status; }
BOOLEAN ndisprotRegisterExCallBack() { OBJECT_ATTRIBUTES ObjectAttr; UNICODE_STRING CallBackObjectName; NTSTATUS Status; BOOLEAN bResult = TRUE; DEBUGP(DL_LOUD, ("--> ndisprotRegisterExCallBack\n")); PAGED_CODE(); do { RtlInitUnicodeString(&CallBackObjectName, NDISPROT_CALLBACK_NAME); InitializeObjectAttributes(&ObjectAttr, &CallBackObjectName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL); Status = ExCreateCallback(&CallbackObject, &ObjectAttr, TRUE, TRUE); if (!NT_SUCCESS(Status)) { DEBUGP(DL_ERROR, ("RegisterExCallBack: failed to create callback %lx\n", Status)); bResult = FALSE; break; } CallbackRegisterationHandle = ExRegisterCallback(CallbackObject, ndisprotCallback, (PVOID)NULL); if (CallbackRegisterationHandle == NULL) { DEBUGP(DL_ERROR,("RegisterExCallBack: failed to register a Callback routine%lx\n", Status)); bResult = FALSE; break; } ExNotifyCallback(CallbackObject, (PVOID)CALLBACK_SOURCE_NDISPROT, (PVOID)NULL); }WHILE(FALSE); if(!bResult) { if (CallbackRegisterationHandle) { ExUnregisterCallback(CallbackRegisterationHandle); CallbackRegisterationHandle = NULL; } if (CallbackObject) { ObDereferenceObject(CallbackObject); CallbackObject = NULL; } } DEBUGP(DL_LOUD, ("<-- ndisprotRegisterExCallBack\n")); return bResult; }
NTSTATUS NICInitiateDmaTransfer( IN PFDO_DATA FdoData, IN WDFREQUEST Request ) { WDFDMATRANSACTION dmaTransaction; NTSTATUS status; BOOLEAN bCreated = FALSE; do { // // Create a new DmaTransaction. // status = WdfDmaTransactionCreate( FdoData->WdfDmaEnabler, WDF_NO_OBJECT_ATTRIBUTES, &dmaTransaction ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "WdfDmaTransactionCreate failed %X\n", status); break; } bCreated = TRUE; // // Initialize the new DmaTransaction. // status = WdfDmaTransactionInitializeUsingRequest( dmaTransaction, Request, NICEvtProgramDmaFunction, WdfDmaDirectionWriteToDevice ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "WdfDmaTransactionInitalizeUsingRequest failed %X\n", status); break; } // // Execute this DmaTransaction. // status = WdfDmaTransactionExecute( dmaTransaction, dmaTransaction ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "WdfDmaTransactionExecute failed %X\n", status); break; } } WHILE (FALSE); if(!NT_SUCCESS(status)){ if(bCreated) { WdfObjectDelete( dmaTransaction ); } } return status; }
int _cdecl main( _In_ int argc, _In_ char *argv[] ) { HDEVINFO hardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0, bytes=0; HANDLE file; ULONG i =0; KEYBOARD_ATTRIBUTES kbdattrib; UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(argv); // // Open a handle to the device interface information set of all // present toaster class interfaces. // hardwareDeviceInfo = SetupDiGetClassDevs ( (LPGUID)&GUID_DEVINTERFACE_KBFILTER, NULL, // Define no enumerator (global) NULL, // Define no (DIGCF_PRESENT | // Only Devices present DIGCF_DEVICEINTERFACE)); // Function class devices. if(INVALID_HANDLE_VALUE == hardwareDeviceInfo) { printf("SetupDiGetClassDevs failed: %x\n", GetLastError()); return 0; } deviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); printf("\nList of KBFILTER Device Interfaces\n"); printf("---------------------------------\n"); i = 0; // // Enumerate devices of toaster class // do { if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo, 0, // No care about specific PDOs (LPGUID)&GUID_DEVINTERFACE_KBFILTER, i, // &deviceInterfaceData)) { if(deviceInterfaceDetailData) { free (deviceInterfaceDetailData); deviceInterfaceDetailData = NULL; } // // Allocate a function class device data structure to // receive the information about this particular device. // // // First find out required length of the buffer // if(!SetupDiGetDeviceInterfaceDetail ( hardwareDeviceInfo, &deviceInterfaceData, NULL, // probing so no output buffer yet 0, // probing so output buffer length of zero &requiredLength, NULL)) { // not interested in the specific dev-node if(ERROR_INSUFFICIENT_BUFFER != GetLastError()) { printf("SetupDiGetDeviceInterfaceDetail failed %d\n", GetLastError()); SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return FALSE; } } predictedLength = requiredLength; deviceInterfaceDetailData = malloc (predictedLength); if(deviceInterfaceDetailData) { deviceInterfaceDetailData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); } else { printf("Couldn't allocate %d bytes for device interface details.\n", predictedLength); SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return FALSE; } if (! SetupDiGetDeviceInterfaceDetail ( hardwareDeviceInfo, &deviceInterfaceData, deviceInterfaceDetailData, predictedLength, &requiredLength, NULL)) { printf("Error in SetupDiGetDeviceInterfaceDetail\n"); SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); free (deviceInterfaceDetailData); return FALSE; } printf("%d) %s\n", ++i, deviceInterfaceDetailData->DevicePath); } else if (ERROR_NO_MORE_ITEMS != GetLastError()) { free (deviceInterfaceDetailData); deviceInterfaceDetailData = NULL; continue; } else break; } WHILE (TRUE); SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); if(!deviceInterfaceDetailData) { printf("No device interfaces present\n"); return 0; } // // Open the last toaster device interface // printf("\nOpening the last interface:\n %s\n", deviceInterfaceDetailData->DevicePath); file = CreateFile ( deviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, // no SECURITY_ATTRIBUTES structure OPEN_EXISTING, // No special create flags 0, // No special attributes NULL); if (INVALID_HANDLE_VALUE == file) { printf("Error in CreateFile: %x", GetLastError()); free (deviceInterfaceDetailData); return 0; } // // Send an IOCTL to retrive the keyboard attributes // These are cached in the kbfiltr // if (!DeviceIoControl (file, IOCTL_KBFILTR_GET_KEYBOARD_ATTRIBUTES, NULL, 0, &kbdattrib, sizeof(kbdattrib), &bytes, NULL)) { printf("Retrieve Keyboard Attributes request failed:0x%x\n", GetLastError()); free (deviceInterfaceDetailData); CloseHandle(file); return 0; } printf("\nKeyboard Attributes:\n" " KeyboardMode: 0x%x\n" " NumberOfFunctionKeys: 0x%x\n" " NumberOfIndicators: 0x%x\n" " NumberOfKeysTotal: 0x%x\n" " InputDataQueueLength: 0x%x\n", kbdattrib.KeyboardMode, kbdattrib.NumberOfFunctionKeys, kbdattrib.NumberOfIndicators, kbdattrib.NumberOfKeysTotal, kbdattrib.InputDataQueueLength); free (deviceInterfaceDetailData); CloseHandle(file); return 0; }
void gen8_vec4_generator::generate_vec4_instruction(vec4_instruction *instruction, struct brw_reg dst, struct brw_reg *src) { vec4_instruction *ir = (vec4_instruction *) instruction; if (dst.width == BRW_WIDTH_4) { /* This happens in attribute fixups for "dual instanced" geometry * shaders, since they use attributes that are vec4's. Since the exec * width is only 4, it's essential that the caller set * force_writemask_all in order to make sure the instruction is executed * regardless of which channels are enabled. */ assert(ir->force_writemask_all); /* Fix up any <8;8,1> or <0;4,1> source registers to <4;4,1> to satisfy * the following register region restrictions (from Graphics BSpec: * 3D-Media-GPGPU Engine > EU Overview > Registers and Register Regions * > Register Region Restrictions) * * 1. ExecSize must be greater than or equal to Width. * * 2. If ExecSize = Width and HorzStride != 0, VertStride must be set * to Width * HorzStride." */ for (int i = 0; i < 3; i++) { if (src[i].file == BRW_GENERAL_REGISTER_FILE) src[i] = stride(src[i], 4, 4, 1); } } switch (ir->opcode) { case BRW_OPCODE_MOV: MOV(dst, src[0]); break; case BRW_OPCODE_ADD: ADD(dst, src[0], src[1]); break; case BRW_OPCODE_MUL: MUL(dst, src[0], src[1]); break; case BRW_OPCODE_MACH: MACH(dst, src[0], src[1]); break; case BRW_OPCODE_MAD: MAD(dst, src[0], src[1], src[2]); break; case BRW_OPCODE_FRC: FRC(dst, src[0]); break; case BRW_OPCODE_RNDD: RNDD(dst, src[0]); break; case BRW_OPCODE_RNDE: RNDE(dst, src[0]); break; case BRW_OPCODE_RNDZ: RNDZ(dst, src[0]); break; case BRW_OPCODE_AND: AND(dst, src[0], src[1]); break; case BRW_OPCODE_OR: OR(dst, src[0], src[1]); break; case BRW_OPCODE_XOR: XOR(dst, src[0], src[1]); break; case BRW_OPCODE_NOT: NOT(dst, src[0]); break; case BRW_OPCODE_ASR: ASR(dst, src[0], src[1]); break; case BRW_OPCODE_SHR: SHR(dst, src[0], src[1]); break; case BRW_OPCODE_SHL: SHL(dst, src[0], src[1]); break; case BRW_OPCODE_CMP: CMP(dst, ir->conditional_mod, src[0], src[1]); break; case BRW_OPCODE_SEL: SEL(dst, src[0], src[1]); break; case BRW_OPCODE_DPH: DPH(dst, src[0], src[1]); break; case BRW_OPCODE_DP4: DP4(dst, src[0], src[1]); break; case BRW_OPCODE_DP3: DP3(dst, src[0], src[1]); break; case BRW_OPCODE_DP2: DP2(dst, src[0], src[1]); break; case BRW_OPCODE_F32TO16: F32TO16(dst, src[0]); break; case BRW_OPCODE_F16TO32: F16TO32(dst, src[0]); break; case BRW_OPCODE_LRP: LRP(dst, src[0], src[1], src[2]); break; case BRW_OPCODE_BFREV: /* BFREV only supports UD type for src and dst. */ BFREV(retype(dst, BRW_REGISTER_TYPE_UD), retype(src[0], BRW_REGISTER_TYPE_UD)); break; case BRW_OPCODE_FBH: /* FBH only supports UD type for dst. */ FBH(retype(dst, BRW_REGISTER_TYPE_UD), src[0]); break; case BRW_OPCODE_FBL: /* FBL only supports UD type for dst. */ FBL(retype(dst, BRW_REGISTER_TYPE_UD), src[0]); break; case BRW_OPCODE_CBIT: /* CBIT only supports UD type for dst. */ CBIT(retype(dst, BRW_REGISTER_TYPE_UD), src[0]); break; case BRW_OPCODE_ADDC: ADDC(dst, src[0], src[1]); break; case BRW_OPCODE_SUBB: SUBB(dst, src[0], src[1]); break; case BRW_OPCODE_BFE: BFE(dst, src[0], src[1], src[2]); break; case BRW_OPCODE_BFI1: BFI1(dst, src[0], src[1]); break; case BRW_OPCODE_BFI2: BFI2(dst, src[0], src[1], src[2]); break; case BRW_OPCODE_IF: IF(ir->predicate); break; case BRW_OPCODE_ELSE: ELSE(); break; case BRW_OPCODE_ENDIF: ENDIF(); break; case BRW_OPCODE_DO: DO(); break; case BRW_OPCODE_BREAK: BREAK(); break; case BRW_OPCODE_CONTINUE: CONTINUE(); break; case BRW_OPCODE_WHILE: WHILE(); break; case SHADER_OPCODE_RCP: MATH(BRW_MATH_FUNCTION_INV, dst, src[0]); break; case SHADER_OPCODE_RSQ: MATH(BRW_MATH_FUNCTION_RSQ, dst, src[0]); break; case SHADER_OPCODE_SQRT: MATH(BRW_MATH_FUNCTION_SQRT, dst, src[0]); break; case SHADER_OPCODE_EXP2: MATH(BRW_MATH_FUNCTION_EXP, dst, src[0]); break; case SHADER_OPCODE_LOG2: MATH(BRW_MATH_FUNCTION_LOG, dst, src[0]); break; case SHADER_OPCODE_SIN: MATH(BRW_MATH_FUNCTION_SIN, dst, src[0]); break; case SHADER_OPCODE_COS: MATH(BRW_MATH_FUNCTION_COS, dst, src[0]); break; case SHADER_OPCODE_POW: MATH(BRW_MATH_FUNCTION_POW, dst, src[0], src[1]); break; case SHADER_OPCODE_INT_QUOTIENT: MATH(BRW_MATH_FUNCTION_INT_DIV_QUOTIENT, dst, src[0], src[1]); break; case SHADER_OPCODE_INT_REMAINDER: MATH(BRW_MATH_FUNCTION_INT_DIV_REMAINDER, dst, src[0], src[1]); break; case SHADER_OPCODE_TEX: case SHADER_OPCODE_TXD: case SHADER_OPCODE_TXF: case SHADER_OPCODE_TXF_CMS: case SHADER_OPCODE_TXF_MCS: case SHADER_OPCODE_TXL: case SHADER_OPCODE_TXS: case SHADER_OPCODE_TG4: case SHADER_OPCODE_TG4_OFFSET: generate_tex(ir, dst); break; case VS_OPCODE_URB_WRITE: generate_urb_write(ir, true); break; case SHADER_OPCODE_GEN4_SCRATCH_READ: generate_scratch_read(ir, dst, src[0]); break; case SHADER_OPCODE_GEN4_SCRATCH_WRITE: generate_scratch_write(ir, dst, src[0], src[1]); break; case VS_OPCODE_PULL_CONSTANT_LOAD: case VS_OPCODE_PULL_CONSTANT_LOAD_GEN7: generate_pull_constant_load(ir, dst, src[0], src[1]); break; case GS_OPCODE_URB_WRITE: generate_urb_write(ir, false); break; case GS_OPCODE_THREAD_END: generate_gs_thread_end(ir); break; case GS_OPCODE_SET_WRITE_OFFSET: generate_gs_set_write_offset(dst, src[0], src[1]); break; case GS_OPCODE_SET_VERTEX_COUNT: generate_gs_set_vertex_count(dst, src[0]); break; case GS_OPCODE_SET_DWORD_2_IMMED: generate_gs_set_dword_2_immed(dst, src[0]); break; case GS_OPCODE_PREPARE_CHANNEL_MASKS: generate_gs_prepare_channel_masks(dst); break; case GS_OPCODE_SET_CHANNEL_MASKS: generate_gs_set_channel_masks(dst, src[0]); break; case SHADER_OPCODE_SHADER_TIME_ADD: assert(!"XXX: Missing Gen8 vec4 support for INTEL_DEBUG=shader_time"); break; case SHADER_OPCODE_UNTYPED_ATOMIC: assert(!"XXX: Missing Gen8 vec4 support for UNTYPED_ATOMIC"); break; case SHADER_OPCODE_UNTYPED_SURFACE_READ: assert(!"XXX: Missing Gen8 vec4 support for UNTYPED_SURFACE_READ"); break; case VS_OPCODE_UNPACK_FLAGS_SIMD4X2: assert(!"VS_OPCODE_UNPACK_FLAGS_SIMD4X2 should not be used on Gen8+."); break; default: if (ir->opcode < (int) ARRAY_SIZE(opcode_descs)) { _mesa_problem(ctx, "Unsupported opcode in `%s' in VS\n", opcode_descs[ir->opcode].name); } else { _mesa_problem(ctx, "Unsupported opcode %d in VS", ir->opcode); } abort(); } }
BOOLEAN MPAreTwoPatternsEqual( IN PNDIS_PM_PACKET_PATTERN pNdisPattern1, IN PNDIS_PM_PACKET_PATTERN pNdisPattern2 ) /*++ Routine Description: This routine will compare two wake up patterns to see if they are equal Arguments: pNdisPattern1 - Pattern1 pNdisPattern2 - Pattern 2 Return Value: True - if patterns are equal False - Otherwise --*/ { BOOLEAN bEqual = FALSE; // Local variables used later in the compare section of this function PUCHAR pMask1, pMask2; PUCHAR pPattern1, pPattern2; UINT MaskSize, PatternSize; do { bEqual = (BOOLEAN)(pNdisPattern1->Priority == pNdisPattern2->Priority); if (bEqual == FALSE) { break; } bEqual = (BOOLEAN)(pNdisPattern1->MaskSize == pNdisPattern2->MaskSize); if (bEqual == FALSE) { break; } // // Verify the Mask // MaskSize = pNdisPattern1->MaskSize ; pMask1 = (PUCHAR) pNdisPattern1 + sizeof (NDIS_PM_PACKET_PATTERN); pMask2 = (PUCHAR) pNdisPattern2 + sizeof (NDIS_PM_PACKET_PATTERN); bEqual = (BOOLEAN)RtlEqualMemory (pMask1, pMask2, MaskSize); if (bEqual == FALSE) { break; } // // Verify the Pattern // bEqual = (BOOLEAN)(pNdisPattern1->PatternSize == pNdisPattern2->PatternSize); if (bEqual == FALSE) { break; } PatternSize = pNdisPattern2->PatternSize; pPattern1 = (PUCHAR) pNdisPattern1 + pNdisPattern1->PatternOffset; pPattern2 = (PUCHAR) pNdisPattern2 + pNdisPattern2->PatternOffset; bEqual = (BOOLEAN)RtlEqualMemory (pPattern1, pPattern2, PatternSize ); if (bEqual == FALSE) { break; } } WHILE (FALSE); return bEqual; }
NTSTATUS NICReset( IN PFDO_DATA FdoData ) /*++ Routine Description: Function to reset the device. Arguments: FdoData Pointer to our adapter Return Value: NT Status code. Note: NICReset is called at DPC. Take advantage of this fact when acquiring or releasing spinlocks --*/ { NTSTATUS status; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_DPC, "---> MPReset\n"); WdfSpinLockAcquire(FdoData->Lock); WdfSpinLockAcquire(FdoData->SendLock); WdfSpinLockAcquire(FdoData->RcvLock); do { // // Is this adapter already doing a reset? // if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS)) { status = STATUS_SUCCESS; goto exit; } MP_SET_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS); // // Is this adapter doing link detection? // if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_LINK_DETECTION)) { TraceEvents(TRACE_LEVEL_WARNING, DBG_DPC, "Reset is pended...\n"); status = STATUS_SUCCESS; goto exit; } // // Is this adapter going to be removed // if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_NON_RECOVER_ERROR)) { status = STATUS_DEVICE_DATA_ERROR; if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_REMOVE_IN_PROGRESS)) { goto exit; } // This is an unrecoverable hardware failure. // We need to tell NDIS to remove this miniport MP_SET_FLAG(FdoData, fMP_ADAPTER_REMOVE_IN_PROGRESS); MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS); WdfSpinLockRelease(FdoData->RcvLock); WdfSpinLockRelease(FdoData->SendLock); WdfSpinLockRelease(FdoData->Lock); // TODO: Log an entry into the eventlog WdfDeviceSetFailed(FdoData->WdfDevice, WdfDeviceFailedAttemptRestart); TraceEvents(TRACE_LEVEL_FATAL, DBG_DPC, "<--- MPReset, status=%x\n", status); return status; } // // Disable the interrupt and issue a reset to the NIC // NICDisableInterrupt(FdoData); NICIssueSelectiveReset(FdoData); // // Release all the locks and then acquire back the send lock // we are going to clean up the send queues // which may involve calling Ndis APIs // release all the locks before grabbing the send lock to // avoid deadlocks // WdfSpinLockRelease(FdoData->RcvLock); WdfSpinLockRelease(FdoData->SendLock); WdfSpinLockRelease(FdoData->Lock); WdfSpinLockAcquire(FdoData->SendLock); // // Free the packets on SendQueueList // NICFreeQueuedSendPackets(FdoData); // // Free the packets being actively sent & stopped // NICFreeBusySendPackets(FdoData); RtlZeroMemory(FdoData->MpTcbMem, FdoData->MpTcbMemSize); // // Re-initialize the send structures // NICInitSendBuffers(FdoData); WdfSpinLockRelease(FdoData->SendLock); // // get all the locks again in the right order // WdfSpinLockAcquire(FdoData->Lock); WdfSpinLockAcquire(FdoData->SendLock); WdfSpinLockAcquire(FdoData->RcvLock); // // Reset the RFD list and re-start RU // NICResetRecv(FdoData); status = NICStartRecv(FdoData); if (status != STATUS_SUCCESS) { // Are we having failures in a few consecutive resets? if (FdoData->HwErrCount < NIC_HARDWARE_ERROR_THRESHOLD) { // It's not over the threshold yet, let it to continue FdoData->HwErrCount++; } else { // This is an unrecoverable hardware failure. // We need to tell NDIS to remove this miniport MP_SET_FLAG(FdoData, fMP_ADAPTER_REMOVE_IN_PROGRESS); MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS); WdfSpinLockRelease(FdoData->RcvLock); WdfSpinLockRelease(FdoData->SendLock); WdfSpinLockRelease(FdoData->Lock); // TODO: Log an entry into the eventlog // // Tell the system that the device has failed. // WdfDeviceSetFailed(FdoData->WdfDevice, WdfDeviceFailedAttemptRestart); TraceEvents(TRACE_LEVEL_ERROR, DBG_DPC, "<--- MPReset, status=%x\n", status); return(status); } break; } FdoData->HwErrCount = 0; MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_HARDWARE_ERROR); NICEnableInterrupt(FdoData->WdfInterrupt, FdoData); } WHILE (FALSE); MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_RESET_IN_PROGRESS); exit: WdfSpinLockRelease(FdoData->RcvLock); WdfSpinLockRelease(FdoData->SendLock); WdfSpinLockRelease(FdoData->Lock); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_DPC, "<--- MPReset, status=%x\n", status); return(status); }
BOOLEAN SerialISR( IN WDFINTERRUPT Interrupt, IN ULONG MessageID ) /*++ Routine Description: This is the interrupt service routine for the serial port driver. It will determine whether the serial port is the source of this interrupt. If it is, then this routine will do the minimum of processing to quiet the interrupt. It will store any information necessary for later processing. Arguments: InterruptObject - Points to the interrupt object declared for this device. We *do not* use this parameter. Return Value: This function will return TRUE if the serial port is the source of this interrupt, FALSE otherwise. --*/ { // // Holds the information specific to handling this device. // PSERIAL_DEVICE_EXTENSION Extension = NULL; // // Holds the contents of the interrupt identification record. // A low bit of zero in this register indicates that there is // an interrupt pending on this device. // UCHAR InterruptIdReg; // // Will hold whether we've serviced any interrupt causes in this // routine. // BOOLEAN ServicedAnInterrupt; UCHAR tempLSR; PREQUEST_CONTEXT reqContext = NULL; UNREFERENCED_PARAMETER(MessageID); Extension = SerialGetDeviceExtension(WdfInterruptGetDevice(Interrupt)); // // Make sure we have an interrupt pending. If we do then // we need to make sure that the device is open. If the // device isn't open or powered down then quiet the device. Note that // if the device isn't opened when we enter this routine // it can't open while we're in it. // InterruptIdReg = READ_INTERRUPT_ID_REG(Extension, Extension->Controller); if ((InterruptIdReg & SERIAL_IIR_NO_INTERRUPT_PENDING)) { ServicedAnInterrupt = FALSE; } else if (!Extension->DeviceIsOpened/* || (Extension->PowerState != PowerDeviceD0)*/) { // // We got an interrupt with the device being closed or when the // device is supposed to be powered down. This // is not unlikely with a serial device. We just quietly // keep servicing the causes until it calms down. // ServicedAnInterrupt = TRUE; do { InterruptIdReg &= (~SERIAL_IIR_FIFOS_ENABLED); switch (InterruptIdReg) { case SERIAL_IIR_RLS: { READ_LINE_STATUS(Extension, Extension->Controller); break; } case SERIAL_IIR_RDA: case SERIAL_IIR_CTI: { READ_RECEIVE_BUFFER(Extension, Extension->Controller); break; } case SERIAL_IIR_THR: { // // Alread clear from reading the iir. // // We want to keep close track of whether // the holding register is empty. // Extension->HoldingEmpty = TRUE; break; } case SERIAL_IIR_MS: { READ_MODEM_STATUS(Extension, Extension->Controller); break; } default: { ASSERT(FALSE); break; } } } while (!((InterruptIdReg = READ_INTERRUPT_ID_REG(Extension, Extension->Controller)) & SERIAL_IIR_NO_INTERRUPT_PENDING)); } else { ServicedAnInterrupt = TRUE; do { // // We only care about bits that can denote an interrupt. // InterruptIdReg &= SERIAL_IIR_RLS | SERIAL_IIR_RDA | SERIAL_IIR_CTI | SERIAL_IIR_THR | SERIAL_IIR_MS; // // We have an interrupt. We look for interrupt causes // in priority order. The presence of a higher interrupt // will mask out causes of a lower priority. When we service // and quiet a higher priority interrupt we then need to check // the interrupt causes to see if a new interrupt cause is // present. // switch (InterruptIdReg) { case SERIAL_IIR_RLS: { SerialProcessLSR(Extension); break; } case SERIAL_IIR_RDA: case SERIAL_IIR_CTI: { // // Reading the receive buffer will quiet this interrupt. // // It may also reveal a new interrupt cause. // UCHAR ReceivedChar; do { ReceivedChar = READ_RECEIVE_BUFFER(Extension, Extension->Controller); Extension->PerfStats.ReceivedCount++; Extension->WmiPerfData.ReceivedCount++; ReceivedChar &= Extension->ValidDataMask; if (!ReceivedChar && (Extension->HandFlow.FlowReplace & SERIAL_NULL_STRIPPING)) { // // If what we got is a null character // and we're doing null stripping, then // we simply act as if we didn't see it. // goto ReceiveDoLineStatus; } if ((Extension->HandFlow.FlowReplace & SERIAL_AUTO_TRANSMIT) && ((ReceivedChar == Extension->SpecialChars.XonChar) || (ReceivedChar == Extension->SpecialChars.XoffChar))) { // // No matter what happens this character // will never get seen by the app. // if (ReceivedChar == Extension->SpecialChars.XoffChar) { Extension->TXHolding |= SERIAL_TX_XOFF; if ((Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) == SERIAL_TRANSMIT_TOGGLE) { SerialInsertQueueDpc( Extension->StartTimerLowerRTSDpc )?Extension->CountOfTryingToLowerRTS++:0; } } else { if (Extension->TXHolding & SERIAL_TX_XOFF) { // // We got the xon char **AND*** we // were being held up on transmission // by xoff. Clear that we are holding // due to xoff. Transmission will // automatically restart because of // the code outside the main loop that // catches problems chips like the // SMC and the Winbond. // Extension->TXHolding &= ~SERIAL_TX_XOFF; } } goto ReceiveDoLineStatus; } // // Check to see if we should note // the receive character or special // character event. // if (Extension->IsrWaitMask) { if (Extension->IsrWaitMask & SERIAL_EV_RXCHAR) { Extension->HistoryMask |= SERIAL_EV_RXCHAR; } if ((Extension->IsrWaitMask & SERIAL_EV_RXFLAG) && (Extension->SpecialChars.EventChar == ReceivedChar)) { Extension->HistoryMask |= SERIAL_EV_RXFLAG; } if (Extension->IrpMaskLocation && Extension->HistoryMask) { *Extension->IrpMaskLocation = Extension->HistoryMask; Extension->IrpMaskLocation = NULL; Extension->HistoryMask = 0; reqContext = SerialGetRequestContext(Extension->CurrentWaitRequest); reqContext->Information = sizeof(ULONG); SerialInsertQueueDpc( Extension->CommWaitDpc ); } } SerialPutChar( Extension, ReceivedChar ); // // If we're doing line status and modem // status insertion then we need to insert // a zero following the character we just // placed into the buffer to mark that this // was reception of what we are using to // escape. // if (Extension->EscapeChar && (Extension->EscapeChar == ReceivedChar)) { SerialPutChar( Extension, SERIAL_LSRMST_ESCAPE ); } ReceiveDoLineStatus: ; // // This reads the interrupt ID register and detemines if bits are 0 // If either of the reserved bits are 1, we stop servicing interrupts // Since this detection method is not guarenteed this is enabled via // a registry entry "UartDetectRemoval" and intialized on DriverEntry. // This is disabled by default and will only be enabled on Stratus systems // that allow hot replacement of serial cards // if(Extension->UartRemovalDetect) { UCHAR DetectRemoval; DetectRemoval = READ_INTERRUPT_ID_REG(Extension, Extension->Controller); if(DetectRemoval & SERIAL_IIR_MUST_BE_ZERO) { // break out of this loop and stop processing interrupts break; } } if (!((tempLSR = SerialProcessLSR(Extension)) & SERIAL_LSR_DR)) { // // No more characters, get out of the // loop. // break; } if ((tempLSR & ~(SERIAL_LSR_THRE | SERIAL_LSR_TEMT | SERIAL_LSR_DR)) && Extension->EscapeChar) { // // An error was indicated and inserted into the // stream, get out of the loop. // break; } } WHILE (TRUE); break; } case SERIAL_IIR_THR: { doTrasmitStuff:; Extension->HoldingEmpty = TRUE; if (Extension->WriteLength || Extension->TransmitImmediate || Extension->SendXoffChar || Extension->SendXonChar) { // // Even though all of the characters being // sent haven't all been sent, this variable // will be checked when the transmit queue is // empty. If it is still true and there is a // wait on the transmit queue being empty then // we know we finished transmitting all characters // following the initiation of the wait since // the code that initiates the wait will set // this variable to false. // // One reason it could be false is that // the writes were cancelled before they // actually started, or that the writes // failed due to timeouts. This variable // basically says a character was written // by the isr at some point following the // initiation of the wait. // Extension->EmptiedTransmit = TRUE; // // If we have output flow control based on // the modem status lines, then we have to do // all the modem work before we output each // character. (Otherwise we might miss a // status line change.) // if (Extension->HandFlow.ControlHandShake & SERIAL_OUT_HANDSHAKEMASK) { SerialHandleModemUpdate( Extension, TRUE ); } // // We can only send the xon character if // the only reason we are holding is because // of the xoff. (Hardware flow control or // sending break preclude putting a new character // on the wire.) // if (Extension->SendXonChar && !(Extension->TXHolding & ~SERIAL_TX_XOFF)) { if ((Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) == SERIAL_TRANSMIT_TOGGLE) { // // We have to raise if we're sending // this character. // SerialSetRTS(Extension->WdfInterrupt, Extension); Extension->PerfStats.TransmittedCount++; Extension->WmiPerfData.TransmittedCount++; WRITE_TRANSMIT_HOLDING(Extension, Extension->Controller, Extension->SpecialChars.XonChar); SerialInsertQueueDpc( Extension->StartTimerLowerRTSDpc )?Extension->CountOfTryingToLowerRTS++:0; } else { Extension->PerfStats.TransmittedCount++; Extension->WmiPerfData.TransmittedCount++; WRITE_TRANSMIT_HOLDING(Extension, Extension->Controller, Extension->SpecialChars.XonChar); } Extension->SendXonChar = FALSE; Extension->HoldingEmpty = FALSE; // // If we send an xon, by definition we // can't be holding by Xoff. // Extension->TXHolding &= ~SERIAL_TX_XOFF; // // If we are sending an xon char then // by definition we can't be "holding" // up reception by Xoff. // Extension->RXHolding &= ~SERIAL_RX_XOFF; } else if (Extension->SendXoffChar && !Extension->TXHolding) { if ((Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) == SERIAL_TRANSMIT_TOGGLE) { // // We have to raise if we're sending // this character. // SerialSetRTS(Extension->WdfInterrupt, Extension); Extension->PerfStats.TransmittedCount++; Extension->WmiPerfData.TransmittedCount++; WRITE_TRANSMIT_HOLDING(Extension, Extension->Controller, Extension->SpecialChars.XoffChar); SerialInsertQueueDpc( Extension->StartTimerLowerRTSDpc )?Extension->CountOfTryingToLowerRTS++:0; } else { Extension->PerfStats.TransmittedCount++; Extension->WmiPerfData.TransmittedCount++; WRITE_TRANSMIT_HOLDING(Extension, Extension->Controller, Extension->SpecialChars.XoffChar); } // // We can't be sending an Xoff character // if the transmission is already held // up because of Xoff. Therefore, if we // are holding then we can't send the char. // // // If the application has set xoff continue // mode then we don't actually stop sending // characters if we send an xoff to the other // side. // if (!(Extension->HandFlow.FlowReplace & SERIAL_XOFF_CONTINUE)) { Extension->TXHolding |= SERIAL_TX_XOFF; if ((Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) == SERIAL_TRANSMIT_TOGGLE) { SerialInsertQueueDpc( Extension->StartTimerLowerRTSDpc )?Extension->CountOfTryingToLowerRTS++:0; } } Extension->SendXoffChar = FALSE; Extension->HoldingEmpty = FALSE; // // Even if transmission is being held // up, we should still transmit an immediate // character if all that is holding us // up is xon/xoff (OS/2 rules). // } else if (Extension->TransmitImmediate && (!Extension->TXHolding || (Extension->TXHolding == SERIAL_TX_XOFF) )) { Extension->TransmitImmediate = FALSE; if ((Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) == SERIAL_TRANSMIT_TOGGLE) { // // We have to raise if we're sending // this character. // SerialSetRTS(Extension->WdfInterrupt, Extension); Extension->PerfStats.TransmittedCount++; Extension->WmiPerfData.TransmittedCount++; WRITE_TRANSMIT_HOLDING(Extension, Extension->Controller, Extension->ImmediateChar); SerialInsertQueueDpc( Extension->StartTimerLowerRTSDpc )?Extension->CountOfTryingToLowerRTS++:0; } else { Extension->PerfStats.TransmittedCount++; Extension->WmiPerfData.TransmittedCount++; WRITE_TRANSMIT_HOLDING(Extension, Extension->Controller, Extension->ImmediateChar); } Extension->HoldingEmpty = FALSE; SerialInsertQueueDpc( Extension->CompleteImmediateDpc ); } else if (!Extension->TXHolding) { ULONG amountToWrite; if (Extension->FifoPresent) { amountToWrite = (Extension->TxFifoAmount < Extension->WriteLength)? Extension->TxFifoAmount: Extension->WriteLength; } else { amountToWrite = 1; } if ((Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) == SERIAL_TRANSMIT_TOGGLE) { // // We have to raise if we're sending // this character. // SerialSetRTS(Extension->WdfInterrupt, Extension); if (amountToWrite == 1) { Extension->PerfStats.TransmittedCount++; Extension->WmiPerfData.TransmittedCount++; WRITE_TRANSMIT_HOLDING(Extension, Extension->Controller, *(Extension->WriteCurrentChar)); } else { Extension->PerfStats.TransmittedCount += amountToWrite; Extension->WmiPerfData.TransmittedCount += amountToWrite; WRITE_TRANSMIT_FIFO_HOLDING(Extension, Extension->Controller, Extension->WriteCurrentChar, amountToWrite); } SerialInsertQueueDpc( Extension->StartTimerLowerRTSDpc )?Extension->CountOfTryingToLowerRTS++:0; } else { if (amountToWrite == 1) { Extension->PerfStats.TransmittedCount++; Extension->WmiPerfData.TransmittedCount++; WRITE_TRANSMIT_HOLDING(Extension, Extension->Controller, *(Extension->WriteCurrentChar)); } else { Extension->PerfStats.TransmittedCount += amountToWrite; Extension->WmiPerfData.TransmittedCount += amountToWrite; WRITE_TRANSMIT_FIFO_HOLDING(Extension, Extension->Controller, Extension->WriteCurrentChar, amountToWrite); } } Extension->HoldingEmpty = FALSE; Extension->WriteCurrentChar += amountToWrite; Extension->WriteLength -= amountToWrite; if (!Extension->WriteLength) { // // No More characters left. This // write is complete. Take care // when updating the information field, // we could have an xoff counter masquerading // as a write request. // reqContext = SerialGetRequestContext(Extension->CurrentWriteRequest); reqContext->Information = (reqContext->MajorFunction == IRP_MJ_WRITE)? (reqContext->Length): (1); SerialInsertQueueDpc( Extension->CompleteWriteDpc ); } } } break; } case SERIAL_IIR_MS: { SerialHandleModemUpdate( Extension, FALSE ); break; } } } while (!((InterruptIdReg = READ_INTERRUPT_ID_REG(Extension, Extension->Controller)) & SERIAL_IIR_NO_INTERRUPT_PENDING)); // // Besides catching the WINBOND and SMC chip problems this // will also cause transmission to restart incase of an xon // char being received. Don't remove. // if (SerialProcessLSR(Extension) & SERIAL_LSR_THRE) { if (!Extension->TXHolding && (Extension->WriteLength || Extension->TransmitImmediate)) { goto doTrasmitStuff; } } } return ServicedAnInterrupt; }
NTSTATUS NICAddWakeUpPattern( IN PFDO_DATA FdoData, IN PVOID InformationBuffer, IN UINT InformationBufferLength, OUT PULONG BytesRead, OUT PULONG BytesNeeded ) /*++ Routine Description: This routine will allocate a local memory structure, copy the pattern, insert the pattern into a linked list and return success We are gauranteed that we wll get only one request at a time, so this is implemented without locks. Arguments: FdoData FdoData structure InformationBuffer Wake up Pattern InformationBufferLength Wake Up Pattern Length Return Value: STATUS_Success - if successful. STATUS_UNSUCCESSFUL - if memory allocation fails. --*/ { NTSTATUS status = STATUS_UNSUCCESSFUL; PMP_WAKE_PATTERN pWakeUpPattern = NULL; ULONG AllocationLength = 0; PNDIS_PM_PACKET_PATTERN pPmPattern = NULL; ULONG Signature = 0; ULONG CopyLength = 0; ULONG safeAddResult; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "--> NICAddWakeUpPattern\n"); do { if(!FdoData->AllowWakeArming) { status = STATUS_NOT_SUPPORTED; break; } pPmPattern = (PNDIS_PM_PACKET_PATTERN) InformationBuffer; if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN)) { status = STATUS_BUFFER_TOO_SMALL; *BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN); break; } // // safeAddResult = pPmPattern->PatternOffset + pPmPattern->PatternSize // status = RtlULongAdd( pPmPattern->PatternOffset, pPmPattern->PatternSize, &safeAddResult) ; if (!NT_SUCCESS(status)) { break; } if (InformationBufferLength < safeAddResult) { status = STATUS_BUFFER_TOO_SMALL; *BytesNeeded = safeAddResult; break; } *BytesRead = safeAddResult; // // Calculate the e100 signature // status = MPCalculateE100PatternForFilter ( (PUCHAR)pPmPattern+ pPmPattern->PatternOffset, pPmPattern->PatternSize, (PUCHAR)pPmPattern +sizeof(NDIS_PM_PACKET_PATTERN), pPmPattern->MaskSize, &Signature ); if ( status != STATUS_SUCCESS) { break; } CopyLength = safeAddResult; // // Allocate the memory to hold the WakeUp Pattern // // AllocationLength = sizeof (MP_WAKE_PATTERN) + CopyLength; // status = RtlULongAdd( sizeof(MP_WAKE_PATTERN), CopyLength, &AllocationLength); if (!NT_SUCCESS(status)) { break; } pWakeUpPattern = ExAllocatePoolWithTag(NonPagedPool, AllocationLength, PCIDRV_POOL_TAG); if (!pWakeUpPattern) { break; } // // Initialize pWakeUpPattern // RtlZeroMemory (pWakeUpPattern, AllocationLength); pWakeUpPattern->AllocationSize = AllocationLength; pWakeUpPattern->Signature = Signature; // // Copy the pattern into local memory // RtlMoveMemory (&pWakeUpPattern->Pattern[0], InformationBuffer, CopyLength); ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); // // Insert the pattern into the list // /* ExInterlockedInsertHeadList (&FdoData->PoMgmt.PatternList, &pWakeUpPattern->linkListEntry, &FdoData->Lock); */ WdfSpinLockAcquire(FdoData->Lock); InsertHeadList(&FdoData->PoMgmt.PatternList,&pWakeUpPattern->linkListEntry ); WdfSpinLockRelease(FdoData->Lock); status = STATUS_SUCCESS; } WHILE (FALSE); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "<-- NICAddWakeUpPattern\n"); return status; }
NTSTATUS MPCalculateE100PatternForFilter ( IN PUCHAR pFrame, IN ULONG FrameLength, IN PUCHAR pMask, IN ULONG MaskLength, OUT PULONG pSignature ) /*++ Routine Description: This function outputs the E100 specific Pattern Signature used to wake up the machine. Section C.2.4 - CRC word calculation of a Flexible Filer Arguments: pFrame - Pattern Set by the protocols FrameLength - Length of the Pattern pMask - Mask set by the Protocols MaskLength - Length of the Mask pSignature - caller allocated return structure Return Value: Returns Success Failure - if the Pattern is greater than 129 bytes --*/ { const ULONG Coefficients = 0x04c11db7; ULONG Signature = 0; ULONG n = 0; ULONG i= 0; PUCHAR pCurrentMaskByte = pMask - 1; // init to -1 ULONG MaskOffset = 0; ULONG BitOffsetInMask = 0; ULONG MaskBit = 0; ULONG ShiftBy = 0; UCHAR FrameByte = 0; NTSTATUS status = STATUS_UNSUCCESSFUL; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "--> MPCalculateE100PatternForFilter\n"); *pSignature = 0; do { if (FrameLength > 128) { status = STATUS_UNSUCCESSFUL; break; } // The E100 driver can only accept 3 DWORDS of Mask in a single pattern if (MaskLength > (3*sizeof(ULONG))) { status = STATUS_UNSUCCESSFUL; break; } for (n=i=0;(n<128) && (n < FrameLength); ++n) { // The first half deals with the question - // Is the nth Frame byte to be included in the Filter // BitOffsetInMask = (n % 8); if (BitOffsetInMask == 0) { // // We need to move to a new byte. // [0] for 0th byte, [1] for 8th byte, [2] for 16th byte, etc. // MaskOffset = n/8; // This is the new byte we need to go // // if (MaskOffset == MaskLength) { break; } pCurrentMaskByte ++; ASSERT (*pCurrentMaskByte == pMask[n/8]); } // Now look at the actual bit in the mask MaskBit = 1 << BitOffsetInMask ; // If the current Mask Bit is set in the Mask then // we need to use it in the CRC calculation, otherwise we ignore it if (! (MaskBit & pCurrentMaskByte[0])) { continue; } // We are suppossed to take in the current byte as part of the CRC calculation // Initialize the variables FrameByte = pFrame[n]; ShiftBy = (i % 3 ) * 8; ASSERT (ShiftBy!= 24); // Bit 24 is never used if (Signature & 0x80000000) { Signature = ((Signature << 1) ^ ( FrameByte << ShiftBy) ^ Coefficients); } else { Signature = ((Signature << 1 ) ^ (FrameByte << ShiftBy)); } ++i; } // Clear bits 22-31 Signature &= 0x00ffffff; // Update the result *pSignature = Signature; // We have succeeded status = STATUS_SUCCESS; } WHILE (FALSE); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "<-- MPCalculateE100PatternForFilter\n"); return status; }
NTSTATUS NICRemoveWakeUpPattern( IN PFDO_DATA FdoData, IN PVOID InformationBuffer, IN UINT InformationBufferLength, OUT PULONG BytesRead, OUT PULONG BytesNeeded ) /*++ Routine Description: This routine will walk the list of wake up pattern and attempt to match the wake up pattern. If it finds a copy , it will remove that WakeUpPattern Arguments: FdoData FdoData structure InformationBuffer Wake up Pattern InformationBufferLength Wake Up Pattern Length Return Value: Success - if successful. STATUS_UNSUCCESSFUL - if memory allocation fails. --*/ { NTSTATUS status = STATUS_UNSUCCESSFUL; PNDIS_PM_PACKET_PATTERN pReqPattern = (PNDIS_PM_PACKET_PATTERN)InformationBuffer; PLIST_ENTRY pPatternEntry = ListNext(&FdoData->PoMgmt.PatternList) ; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "--> NICRemoveWakeUpPattern\n"); do { if(!FdoData->AllowWakeArming) { status = STATUS_NOT_SUPPORTED; break; } if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN)) { status = STATUS_BUFFER_TOO_SMALL; *BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN); break; } if (InformationBufferLength < pReqPattern->PatternOffset + pReqPattern->PatternSize) { status = STATUS_BUFFER_TOO_SMALL; *BytesNeeded = pReqPattern->PatternOffset + pReqPattern->PatternSize; break; } *BytesRead = pReqPattern->PatternOffset + pReqPattern->PatternSize; while (pPatternEntry != (&FdoData->PoMgmt.PatternList)) { BOOLEAN bIsThisThePattern = FALSE; PMP_WAKE_PATTERN pWakeUpPattern = NULL; PNDIS_PM_PACKET_PATTERN pCurrPattern = NULL;; // // initialize local variables // pWakeUpPattern = CONTAINING_RECORD(pPatternEntry, MP_WAKE_PATTERN, linkListEntry); pCurrPattern = (PNDIS_PM_PACKET_PATTERN)&pWakeUpPattern->Pattern[0]; // // increment the iterator // pPatternEntry = ListNext (pPatternEntry); // // Begin Check : Is (pCurrPattern == pReqPattern) // bIsThisThePattern = MPAreTwoPatternsEqual(pReqPattern, pCurrPattern); if (bIsThisThePattern == TRUE) { // // we have a match - remove the entry // RemoveEntryList (&pWakeUpPattern->linkListEntry); // // Free the entry // ExFreePoolWithTag(pWakeUpPattern, PCIDRV_POOL_TAG); status = STATUS_SUCCESS; break; } } } WHILE (FALSE); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER, "<-- NICRemoveWakeUpPattern\n"); return status; }
int _cdecl main( _In_ int argc, _In_ char *argv[] ) { BOOLEAN clearProfile = FALSE; BOOLEAN jsonLoaded = FALSE; cJSON * jsonRoot; // Initialize scan code array KbProfiler_InitScanCodes(); // Initialize profile PROFILE profile; KbProfiler_ClearProfile(&profile); /** * Parse arguments */ for (INT a = 1; a < argc; a++) { char param[2048]; char cmdBase[2048]; char cmdValue[2048]; strcpy(param, argv[a]); char *p = strchr(param, '='); // Single argument if (!p) { strcpy(cmdBase, param); } // Argument with value else { *p++; strcpy(cmdValue, p); strncpy(cmdBase, param, sizeof(p) - 1); cmdBase[sizeof(p) - 1] = '\0'; // Profile arguments if (strcmp(cmdBase, "profile") == 0) { // Clear profile if (strcmp(cmdValue, "clear") == 0) { printf("Clearing profile.\n"); clearProfile = TRUE; } // Load profile else { FILE *f; if (f = fopen(cmdValue, "rb")) { fseek(f, 0, SEEK_END); long fsize = ftell(f); fseek(f, 0, SEEK_SET); char *json = malloc(fsize + 1); fread(json, fsize, 1, f); fclose(f); jsonRoot = cJSON_Parse(json); jsonLoaded = TRUE; } else { printf("Profile JSON file does not exist there."); } } } } } // Parse profile profile.empty = FALSE; if (clearProfile) { profile.empty = TRUE; } if (jsonLoaded == TRUE) { KbProfiler_ParseProfileJSON(jsonRoot, &profile); cJSON_Delete(jsonRoot); } /** * END USER STUFF */ HDEVINFO hardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0, bytes = 0, profileBytes = 0; HANDLE file; ULONG i = 0; KEYBOARD_ATTRIBUTES kbdattrib; UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(argv); // // Open a handle to the device interface information set of all // present toaster class interfaces. // hardwareDeviceInfo = SetupDiGetClassDevs( (LPGUID)&GUID_DEVINTERFACE_KBFILTER, NULL, // Define no enumerator (global) NULL, // Define no (DIGCF_PRESENT | // Only Devices present DIGCF_DEVICEINTERFACE)); // Function class devices. if (INVALID_HANDLE_VALUE == hardwareDeviceInfo) { printf("SetupDiGetClassDevs failed: %x\n", GetLastError()); return 0; } deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); printf("\nList of KBFILTER Device Interfaces\n"); printf("---------------------------------\n"); i = 0; // // Enumerate devices of toaster class // do { if (SetupDiEnumDeviceInterfaces(hardwareDeviceInfo, 0, // No care about specific PDOs (LPGUID)&GUID_DEVINTERFACE_KBFILTER, i, // &deviceInterfaceData)) { if (deviceInterfaceDetailData) { free(deviceInterfaceDetailData); deviceInterfaceDetailData = NULL; } // // Allocate a function class device data structure to // receive the information about this particular device. // // // First find out required length of the buffer // if (!SetupDiGetDeviceInterfaceDetail( hardwareDeviceInfo, &deviceInterfaceData, NULL, // probing so no output buffer yet 0, // probing so output buffer length of zero &requiredLength, NULL)) { // not interested in the specific dev-node if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { printf("SetupDiGetDeviceInterfaceDetail failed %d\n", GetLastError()); SetupDiDestroyDeviceInfoList(hardwareDeviceInfo); return FALSE; } } predictedLength = requiredLength; deviceInterfaceDetailData = malloc(predictedLength); if (deviceInterfaceDetailData) { deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); } else { printf("Couldn't allocate %d bytes for device interface details.\n", predictedLength); SetupDiDestroyDeviceInfoList(hardwareDeviceInfo); return FALSE; } if (!SetupDiGetDeviceInterfaceDetail( hardwareDeviceInfo, &deviceInterfaceData, deviceInterfaceDetailData, predictedLength, &requiredLength, NULL)) { printf("Error in SetupDiGetDeviceInterfaceDetail\n"); SetupDiDestroyDeviceInfoList(hardwareDeviceInfo); free(deviceInterfaceDetailData); return FALSE; } printf("%d) %s\n", ++i, deviceInterfaceDetailData->DevicePath); } else if (ERROR_NO_MORE_ITEMS != GetLastError()) { free(deviceInterfaceDetailData); deviceInterfaceDetailData = NULL; continue; } else break; } WHILE(TRUE); SetupDiDestroyDeviceInfoList(hardwareDeviceInfo); if (!deviceInterfaceDetailData) { printf("No device interfaces present\n"); return 0; } // // Open the last toaster device interface // printf("\nOpening the last interface:\n %s\n", deviceInterfaceDetailData->DevicePath); file = CreateFile(deviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, // no SECURITY_ATTRIBUTES structure OPEN_EXISTING, // No special create flags 0, // No special attributes NULL); if (INVALID_HANDLE_VALUE == file) { printf("Error in CreateFile: %x", GetLastError()); free(deviceInterfaceDetailData); return 0; } // // Send an IOCTL to retrive the keyboard attributes // These are cached in the kbfiltr // if (!DeviceIoControl(file, IOCTL_KBFILTR_GET_KEYBOARD_ATTRIBUTES, NULL, 0, &kbdattrib, sizeof(kbdattrib), &bytes, NULL)) { printf("Retrieve Keyboard Attributes request failed:0x%x\n", GetLastError()); free(deviceInterfaceDetailData); CloseHandle(file); return 0; } printf("\nKeyboard Attributes:\n" " KeyboardMode: 0x%x\n" " NumberOfFunctionKeys: 0x%x\n" " NumberOfIndicators: 0x%x\n" " NumberOfKeysTotal: 0x%x\n" " InputDataQueueLength: 0x%x\n", kbdattrib.KeyboardMode, kbdattrib.NumberOfFunctionKeys, kbdattrib.NumberOfIndicators, kbdattrib.NumberOfKeysTotal, kbdattrib.InputDataQueueLength); printf("Bytes pushed: %d\n", bytes); /** * USER STUFF */ if (!DeviceIoControl(file, IOCTL_KBFILTR_GET_PROFILE, &profile, sizeof(PROFILE), NULL, 0, &profileBytes, NULL)) { printf("Pushing profile failed.\n"); } else { printf("Successfully pushed profile to driver.\n"); printf("Bytes pushed: %d\n", profileBytes); } free(deviceInterfaceDetailData); CloseHandle(file); return 0; }
VOID NICServiceReadIrps( PFDO_DATA FdoData, PMP_RFD *PacketArray, ULONG PacketArrayCount ) /*++ Routine Description: Copy the data from the recv buffers to pending read IRP buffers and complete the IRP. When used as network driver, copy operation can be avoided by devising a private interface between us and the NDIS-WDM filter and have the NDIS-WDM edge to indicate our buffers directly to NDIS. Called at DISPATCH_LEVEL. Take advantage of that fact while acquiring spinlocks. Arguments: FdoData Pointer to our FdoData Return Value: None --*/ { PMP_RFD pMpRfd = NULL; ULONG index; NTSTATUS status; PVOID buffer; WDFREQUEST request; size_t bufLength=0; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "--> NICServiceReadIrps\n"); for(index=0; index < PacketArrayCount; index++) { pMpRfd = PacketArray[index]; ASSERT(pMpRfd); do { status = WdfIoQueueRetrieveNextRequest( FdoData->PendingReadQueue, &request ); if(NT_SUCCESS(status)){ WDF_REQUEST_PARAMETERS params; ULONG length = 0; WDF_REQUEST_PARAMETERS_INIT(¶ms); WdfRequestGetParameters( request, ¶ms ); ASSERT(status == STATUS_SUCCESS); bufLength = params.Parameters.Read.Length; status = WdfRequestRetrieveOutputBuffer(request, bufLength, &buffer, &bufLength); if(NT_SUCCESS(status) ) { length = min((ULONG)bufLength, pMpRfd->PacketSize); RtlCopyMemory(buffer, pMpRfd->Buffer, length); Hexdump((TRACE_LEVEL_VERBOSE, DBG_READ, "Received Packet Data: %!HEXDUMP!\n", log_xstr(buffer, (USHORT)length))); FdoData->BytesReceived += length; } WdfRequestCompleteWithInformation(request, status, length); break; }else { ASSERTMSG("WdfIoQueueRetrieveNextRequest failed", (status == STATUS_NO_MORE_ENTRIES || status == STATUS_WDF_PAUSED)); break; } } WHILE (TRUE); WdfSpinLockAcquire(FdoData->RcvLock); ASSERT(MP_TEST_FLAG(pMpRfd, fMP_RFD_RECV_PEND)); MP_CLEAR_FLAG(pMpRfd, fMP_RFD_RECV_PEND); NICReturnRFD(FdoData, pMpRfd); WdfSpinLockRelease(FdoData->RcvLock); }// end of loop TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "<-- NICServiceReadIrps\n"); return; }