Выделение памяти под массив ExAllocatePool

Тема в разделе "WASM.NT.KERNEL", создана пользователем Mopga, 21 окт 2009.

  1. Mopga

    Mopga Иван

    Публикаций:
    0
    Регистрация:
    21 окт 2009
    Сообщения:
    13
    Адрес:
    Новороссийск
    Память выделяется, но при копировании туда вылетает синяя ошибка с сообщением об ошибке в iotest.sys (то есть в моем драйвере).
    Вот как бы описание:
    Код (Text):
    1. #define INFO_ARRAY_LENGTH 2
    2. struct ipinfo{
    3.     char data[100];
    4. };
    5. struct ipinfo* arr1;
    6. struct ipinfo* arr2;
    7. ULONG Position;
    8.  
    9. .....
    10.  
    11. arr1=ExAllocatePool(PagedPool,INFO_ARRAY_LENGTH*sizeof(struct ipinfo));
    12.     if(arr1==NULL)return 0xC0000000;
    13.     arr2=ExAllocatePool(PagedPool,INFO_ARRAY_LENGTH*sizeof(struct ipinfo));
    14.     if(arr2==NULL){
    15.         ExFreePool(arr1);
    16.         return 0xC0000000;
    17.     }
    18.  
    19. ......
    20.  
    21. if(Position<INFO_ARRAY_LENGTH){
    22.         //sprintf(ptr[Position++].data,"%lx %ld",(ULONG)ptr,counter++);
    23.         strcpy(ptr[Position++].data,"hello");
    24.     }
    Причем если #define INFO_ARRAY_LENGTH 1 то работает, а если больше 1 то все падает.
    В чем может быть косяк?
     
  2. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Что такое ptr ? Да и вообще как-то странно: выделяешь 2 разных куска памяти под ipinfo, а обращаешься к данным, как будто в ptr это массив содержащий 2 таких буффера подряд.. покажи как объявлена и инициализирована эта переменная
     
  3. Folk Acid

    Folk Acid New Member

    Публикаций:
    0
    Регистрация:
    23 авг 2005
    Сообщения:
    432
    Адрес:
    Ukraine
    какой irql?
     
  4. Mopga

    Mopga Иван

    Публикаций:
    0
    Регистрация:
    21 окт 2009
    Сообщения:
    13
    Адрес:
    Новороссийск
    этот ptr переключается между указателями arr1 и arr2
    все работает нормально если объявить arr1 и arr2 просто как массивы типа struct ipinfo arr1[INFO_ARRAY_LENGTH] и struct ipinfo arr2[INFO_ARRAY_LENGTH]


    irql = PASSIVE_LEVEL
     
  5. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    блин, может я адски туплю, но ptr[Position++].data значит, что ptr имеет тип ipinfo* или ipinfo[], если да -- он не может переключаться, покажи, как ты это делаешь =)
     
  6. Mopga

    Mopga Иван

    Публикаций:
    0
    Регистрация:
    21 окт 2009
    Сообщения:
    13
    Адрес:
    Новороссийск
    сначала объявлено в глобальной области видимости:
    Код (Text):
    1. struct ipinfo* ptr; // в глобальной области видимости
    Потом в функции DriverEntry инициализируется ptr и создается поток, который пишет в массив ptr:
    Код (Text):
    1. ptr=arr1;
    2.  
    3. ntStatus = PsCreateSystemThread(&collectThread,THREAD_ALL_ACCESS,NULL,NULL,NULL,CollectThreadFunc,NULL);
    затем в этом потоке идет запись так:
    Код (Text):
    1. void getPacket(void){
    2.     static int counter=0;
    3.  
    4.     LARGE_INTEGER timeout=RtlConvertLongToLargeInteger(-5000000L);
    5.  
    6.     if(Position<INFO_ARRAY_LENGTH){
    7.         //sprintf(ptr[Position++].data,"%lx %ld",(ULONG)ptr,counter++);
    8.         strcpy(ptr[Position++].data,"hello");
    9.     }  
    10.    
    11.     timeout.QuadPart=-3000;
    12.     KeDelayExecutionThread( KernelMode,FALSE,&timeout);
    13. }
    14.  
    15. ULONG continueCollectData(void){
    16.     return KeReadStateEvent(&continueEvent)==0;
    17. }
    18.  
    19. void signalSwap(void){
    20.    
    21.     KIRQL oldIrql;
    22.     KeAcquireSpinLock(&lock, &oldIrql);
    23.    
    24.     if(KeReadStateEvent(&signalSwapEvent)){
    25.         KeClearEvent(&signalSwapEvent);
    26.         if(ptr==arr1)
    27.             ptr=arr2;
    28.         else
    29.             ptr=arr1;
    30.         Size=Position;
    31.         Position=0;
    32.         KeSetEvent(&signalSwappedEvent,IO_NO_INCREMENT,FALSE);     
    33.     }                      
    34.    
    35.     KeReleaseSpinLock(&lock,oldIrql);
    36.    
    37. }
    38. VOID CollectThreadFunc(IN PVOID Context){
    39.     //DVRH_LogMessage("Enter CollectThreadFunc");
    40.     while(continueCollectData()){
    41.         //DVRH_LogMessage("Collect data continuing...");
    42.         getPacket();
    43.         //DVRH_LogMessage("Got packet");
    44.         signalSwap();
    45.            
    46.     }
    47.     //DVRH_LogMessage("Before PsTerminateSystemThread");
    48.     PsTerminateSystemThread(STATUS_SUCCESS);
    49. }
    Затем в функции, которая обрабатывает запросы ввода-вывода идет команда на переключение потока на соседний массив, передачу из свободного массива в ответ на запрос:
    Код (Text):
    1. NTSTATUS
    2. IoTestDeviceControl(
    3.     IN PDEVICE_OBJECT DeviceObject,
    4.     IN PIRP Irp
    5.     )
    6.  
    7. {
    8.     PIO_STACK_LOCATION  irpSp;// Pointer to current stack location
    9.     NTSTATUS            ntStatus = STATUS_SUCCESS;// Assume success
    10.     ULONG               outBufLength; // Output buffer length
    11.     PCHAR               outBuf; // pointer to Input and output buffer
    12.     PCHAR               data = "gu gu gu";
    13.     ULONG               datalen = strlen(data)+1;//Length of data including null
    14.     PMDL                mdl = NULL;
    15.     PCHAR               buffer = NULL;  
    16.     KIRQL                  oldIrql;
    17.     ULONG byteSize;
    18.     static LARGE_INTEGER nWaitTime;
    19.     //DVRH_LogMessage("entering io method");
    20.     nWaitTime=RtlConvertLongToLargeInteger(-100000000L);
    21.    
    22.    
    23.  
    24.     irpSp = IoGetCurrentIrpStackLocation( Irp );
    25.     outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
    26.  
    27.     if(!outBufLength)
    28.     {
    29.         ntStatus = STATUS_INVALID_PARAMETER;
    30.     }else{
    31.  
    32.  
    33.         if ( irpSp->Parameters.DeviceIoControl.IoControlCode == IOTEST_OUT_METHOD){
    34.  
    35.             buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
    36.        
    37.             if(!buffer) {
    38.                 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    39.             }else{
    40.                 //DVRH_LogMessage("setting signal swap");
    41.                 KeSetEvent(&signalSwapEvent,IO_NO_INCREMENT,FALSE);
    42.                 //DVRH_LogMessage("before ntStatus=KeWaitForSingleObject( &signalSwappedEvent, Executive, KernelMode, FALSE, &nWaitTime );");
    43.                 ntStatus=KeWaitForSingleObject( &signalSwappedEvent, Executive, KernelMode, FALSE, &nWaitTime );
    44.                 //DVRH_LogMessage("after swap ");
    45.                
    46.                 if(ntStatus==STATUS_SUCCESS){
    47.                     byteSize=sizeof(struct ipinfo)*Size;
    48.                     if(ptr==arr1)
    49.                         memcpy(buffer, arr2, outBufLength > byteSize ? byteSize : outBufLength);
    50.                     else
    51.                         memcpy(buffer, arr1, outBufLength > byteSize ? byteSize : outBufLength);
    52.  
    53.                     Irp->IoStatus.Information = (outBufLength<Size?outBufLength:byteSize);
    54.                 }
    55.                 else{
    56.                     if(ntStatus==STATUS_TIMEOUT){
    57.                         KeAcquireSpinLock(&lock, &oldIrql);
    58.                         if(KeReadStateEvent(&signalSwappedEvent)){
    59.                             if(ptr==arr1)
    60.                                 ptr=arr2;
    61.                             else
    62.                                 ptr=arr1;
    63.                             Position=Size;
    64.                             Size=0;                        
    65.                         }else{
    66.                             KeClearEvent(&signalSwapEvent);
    67.                         }
    68.                         KeReleaseSpinLock(&lock,oldIrql);
    69.  
    70.                         Irp->IoStatus.Information = 0;
    71.                     }
    72.                 }
    73.                
    74.             }
    75.         }
    76.     }
    77.  
    78.  
    79.     KeClearEvent(&signalSwappedEvent);
    80.     Irp->IoStatus.Status = ntStatus;
    81.  
    82.     IoCompleteRequest( Irp, IO_NO_INCREMENT );
    83.     //DVRH_LogMessage("request completed");
    84.     return ntStatus;
    85. }
    Синий экран вылетает на строке в функции getPacket как только Position становится больше 0:
    Код (Text):
    1. strcpy(ptr[Position++].data,"hello");
     
  7. Mopga

    Mopga Иван

    Публикаций:
    0
    Регистрация:
    21 окт 2009
    Сообщения:
    13
    Адрес:
    Новороссийск
    все проблема решена :)
    просто я балда :)
    инициализировал ptr до выделения памяти :) :
    Код (Text):
    1. ptr=arr1;
    2. arr1=ExAllocatePool(PagedPool,INFO_ARRAY_LENGTH*sizeof(struct ipinfo));
    3.     if(arr1==NULL)return 0xC0000000;
    4.     arr2=ExAllocatePool(PagedPool,INFO_ARRAY_LENGTH*sizeof(struct ipinfo));
    5.     if(arr2==NULL){
    6.         ExFreePool(arr1);
    7.         return 0xC0000000;
    8.     }
     
  8. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    А я вчера действительно адски тупил и не заметил INFO_ARRAY_LENGTH в
    arr1=ExAllocatePool(PagedPool,INFO_ARRAY_LENGTH*sizeof(struct ipinfo)) =)
     
  9. Mopga

    Mopga Иван

    Публикаций:
    0
    Регистрация:
    21 окт 2009
    Сообщения:
    13
    Адрес:
    Новороссийск
    да иногда смотришь по полдня и ничо понять не можешь, вроде все правильно, а работает неправильно, только когда все выведешь до мелочей, тогда только и понимаешь в чем дело
     
  10. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Вероятно, для этих целей и придумали Code Review.
     
  11. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    было бы кого привлечь ;)