Память выделяется, но при копировании туда вылетает синяя ошибка с сообщением об ошибке в iotest.sys (то есть в моем драйвере). Вот как бы описание: Код (Text): #define INFO_ARRAY_LENGTH 2 struct ipinfo{ char data[100]; }; struct ipinfo* arr1; struct ipinfo* arr2; ULONG Position; ..... arr1=ExAllocatePool(PagedPool,INFO_ARRAY_LENGTH*sizeof(struct ipinfo)); if(arr1==NULL)return 0xC0000000; arr2=ExAllocatePool(PagedPool,INFO_ARRAY_LENGTH*sizeof(struct ipinfo)); if(arr2==NULL){ ExFreePool(arr1); return 0xC0000000; } ...... if(Position<INFO_ARRAY_LENGTH){ //sprintf(ptr[Position++].data,"%lx %ld",(ULONG)ptr,counter++); strcpy(ptr[Position++].data,"hello"); } Причем если #define INFO_ARRAY_LENGTH 1 то работает, а если больше 1 то все падает. В чем может быть косяк?
Что такое ptr ? Да и вообще как-то странно: выделяешь 2 разных куска памяти под ipinfo, а обращаешься к данным, как будто в ptr это массив содержащий 2 таких буффера подряд.. покажи как объявлена и инициализирована эта переменная
этот ptr переключается между указателями arr1 и arr2 все работает нормально если объявить arr1 и arr2 просто как массивы типа struct ipinfo arr1[INFO_ARRAY_LENGTH] и struct ipinfo arr2[INFO_ARRAY_LENGTH] irql = PASSIVE_LEVEL
блин, может я адски туплю, но ptr[Position++].data значит, что ptr имеет тип ipinfo* или ipinfo[], если да -- он не может переключаться, покажи, как ты это делаешь =)
сначала объявлено в глобальной области видимости: Код (Text): struct ipinfo* ptr; // в глобальной области видимости Потом в функции DriverEntry инициализируется ptr и создается поток, который пишет в массив ptr: Код (Text): ptr=arr1; ntStatus = PsCreateSystemThread(&collectThread,THREAD_ALL_ACCESS,NULL,NULL,NULL,CollectThreadFunc,NULL); затем в этом потоке идет запись так: Код (Text): void getPacket(void){ static int counter=0; LARGE_INTEGER timeout=RtlConvertLongToLargeInteger(-5000000L); if(Position<INFO_ARRAY_LENGTH){ //sprintf(ptr[Position++].data,"%lx %ld",(ULONG)ptr,counter++); strcpy(ptr[Position++].data,"hello"); } timeout.QuadPart=-3000; KeDelayExecutionThread( KernelMode,FALSE,&timeout); } ULONG continueCollectData(void){ return KeReadStateEvent(&continueEvent)==0; } void signalSwap(void){ KIRQL oldIrql; KeAcquireSpinLock(&lock, &oldIrql); if(KeReadStateEvent(&signalSwapEvent)){ KeClearEvent(&signalSwapEvent); if(ptr==arr1) ptr=arr2; else ptr=arr1; Size=Position; Position=0; KeSetEvent(&signalSwappedEvent,IO_NO_INCREMENT,FALSE); } KeReleaseSpinLock(&lock,oldIrql); } VOID CollectThreadFunc(IN PVOID Context){ //DVRH_LogMessage("Enter CollectThreadFunc"); while(continueCollectData()){ //DVRH_LogMessage("Collect data continuing..."); getPacket(); //DVRH_LogMessage("Got packet"); signalSwap(); } //DVRH_LogMessage("Before PsTerminateSystemThread"); PsTerminateSystemThread(STATUS_SUCCESS); } Затем в функции, которая обрабатывает запросы ввода-вывода идет команда на переключение потока на соседний массив, передачу из свободного массива в ответ на запрос: Код (Text): NTSTATUS IoTestDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PIO_STACK_LOCATION irpSp;// Pointer to current stack location NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success ULONG outBufLength; // Output buffer length PCHAR outBuf; // pointer to Input and output buffer PCHAR data = "gu gu gu"; ULONG datalen = strlen(data)+1;//Length of data including null PMDL mdl = NULL; PCHAR buffer = NULL; KIRQL oldIrql; ULONG byteSize; static LARGE_INTEGER nWaitTime; //DVRH_LogMessage("entering io method"); nWaitTime=RtlConvertLongToLargeInteger(-100000000L); irpSp = IoGetCurrentIrpStackLocation( Irp ); outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; if(!outBufLength) { ntStatus = STATUS_INVALID_PARAMETER; }else{ if ( irpSp->Parameters.DeviceIoControl.IoControlCode == IOTEST_OUT_METHOD){ buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if(!buffer) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; }else{ //DVRH_LogMessage("setting signal swap"); KeSetEvent(&signalSwapEvent,IO_NO_INCREMENT,FALSE); //DVRH_LogMessage("before ntStatus=KeWaitForSingleObject( &signalSwappedEvent, Executive, KernelMode, FALSE, &nWaitTime );"); ntStatus=KeWaitForSingleObject( &signalSwappedEvent, Executive, KernelMode, FALSE, &nWaitTime ); //DVRH_LogMessage("after swap "); if(ntStatus==STATUS_SUCCESS){ byteSize=sizeof(struct ipinfo)*Size; if(ptr==arr1) memcpy(buffer, arr2, outBufLength > byteSize ? byteSize : outBufLength); else memcpy(buffer, arr1, outBufLength > byteSize ? byteSize : outBufLength); Irp->IoStatus.Information = (outBufLength<Size?outBufLength:byteSize); } else{ if(ntStatus==STATUS_TIMEOUT){ KeAcquireSpinLock(&lock, &oldIrql); if(KeReadStateEvent(&signalSwappedEvent)){ if(ptr==arr1) ptr=arr2; else ptr=arr1; Position=Size; Size=0; }else{ KeClearEvent(&signalSwapEvent); } KeReleaseSpinLock(&lock,oldIrql); Irp->IoStatus.Information = 0; } } } } } KeClearEvent(&signalSwappedEvent); Irp->IoStatus.Status = ntStatus; IoCompleteRequest( Irp, IO_NO_INCREMENT ); //DVRH_LogMessage("request completed"); return ntStatus; } Синий экран вылетает на строке в функции getPacket как только Position становится больше 0: Код (Text): strcpy(ptr[Position++].data,"hello");
все проблема решена просто я балда инициализировал ptr до выделения памяти : Код (Text): ptr=arr1; arr1=ExAllocatePool(PagedPool,INFO_ARRAY_LENGTH*sizeof(struct ipinfo)); if(arr1==NULL)return 0xC0000000; arr2=ExAllocatePool(PagedPool,INFO_ARRAY_LENGTH*sizeof(struct ipinfo)); if(arr2==NULL){ ExFreePool(arr1); return 0xC0000000; }
А я вчера действительно адски тупил и не заметил INFO_ARRAY_LENGTH в arr1=ExAllocatePool(PagedPool,INFO_ARRAY_LENGTH*sizeof(struct ipinfo)) =)
да иногда смотришь по полдня и ничо понять не можешь, вроде все правильно, а работает неправильно, только когда все выведешь до мелочей, тогда только и понимаешь в чем дело