Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Неправильно пишет в файл  (Прочитано 15047 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
Игорь98
Новенький

ru
Offline Offline

« : 25-10-2011 11:18 » 

Всем привет. Необходимо что бы драйвер записывал данные в файл. Записывать то он записывает  Улыбаюсь, но вот записывает непонятно что в общем кракозябы какие то. Думаю в чем то ошибся. Вот сама функция которая пишет:
Код: (C++)
VOID WrtFile(UNICODE_STRING nFile, PVOID str)
{
        OBJECT_ATTRIBUTES oa;  
        NTSTATUS opn, wrt;
        IO_STATUS_BLOCK isb;
        HANDLE hFile;  
       
        DbgPrint("Start Writing\n\n");
        DbgPrint("File: %s", str);
       
        InitializeObjectAttributes(&oa, &nFile, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

        opn = ZwOpenFile(&hFile, FILE_WRITE_DATA | SYNCHRONIZE, &oa, &isb,
                        FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT);
        if(opn == STATUS_SUCCESS)
        {
                DbgPrint("OpenFile...YES");            
                wrt = ZwWriteFile(hFile, 0, NULL, NULL, &isb, &str, sizeof(str), NULL, NULL);
                if(wrt == STATUS_SUCCESS)
                {
                        DbgPrint("ZwWriteFile...YES");
                }
                else
                {
                        DbgPrint("ZwWriteFile...NO");
                }
                ZwClose(hFile);
        }
        else
        {
                DbgPrint("OpenFile...NO");
        }
}

А вот кусок кода ее вызова из другой функции:
Код: (C++)
//.......
p = (PVOID)ExAllocatePool(PagedPool, cd);
if(p)
{
        DbgPrint("ExAllocatePool...YES");
}
else
{
        DbgPrint("ExAllocatePool...NO");
}
//.......
WrtFile(nFile, p);     
ExFreePool(p);
//.......
Передача данных из функции в функцию происходит без проблем, а вот запись уже немного хандрит Улыбаюсь
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 25-10-2011 12:17 » 

потому что sizeof(str) ==  sizeof(PVOID) ==4
неверно. это размер указателя.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
zubr
Гость
« Ответ #2 : 25-10-2011 12:22 » 

А что ты хотел получить? Ты в файл записываешь не буфер, а указатель на буфер &str и не весь буфер, а размер указателя sizeof(str), для 32-битных систем это 4 байта.
Записан
oktonion
Постоялец

ru
Offline Offline

« Ответ #3 : 08-11-2011 11:16 » 

Код: (C)
wrt = ZwWriteFile(
                  hFile,
                  0,
                  NULL,
                  NULL,
                  &isb,
                  str,
                  strlen((char*)str),
                  NULL,
                  NULL
                 );
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 09-11-2011 12:02 » 

не надо так делать:  strlen((char*)str)

если целью не является собирание всех разнообразных и неожиданных граблей, то для операций со строками в ядре используются Safe String функции...
в частности RtlStringCbLength
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
oktonion
Постоялец

ru
Offline Offline

« Ответ #5 : 10-11-2011 10:08 » 

Код: (C)
size_t sizeOfStr;
opn = RtlStringCchLengthA(str, 100, &sizeOfStr);
if(opn == STATUS_INVALID_PARAMETER)
  {
       opn = RtlStringCchLengthW(str, 100, &sizeOfStr);
  }

if(opn == STATUS_SUCCESS)
  {
        wrt = ZwWriteFile(
                          hFile,
                          0,
                          NULL,
                          NULL,
                          &isb,
                          str,
                          sizeOfStr,
                          NULL,
                          NULL
                         );
  }
Теперь я прав? Улыбаюсь
« Последнее редактирование: 10-11-2011 10:20 от oktonion » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 10-11-2011 10:55 » 

угу.
правда я не уверен что если  RtlStringCchLengthA возвращает STATUS_INVALID_PARAMETER имеет смысл пробовать RtlStringCchLengthW.... тип строки обычно известен заранее)
и не соображу с ходу - это вообще будет работать? с какой стороны там ноль в юникоде может появится...

PS и с волшебными числами (типа "100") надо аккуратнее... но это уже в контексте программы лучше дефайнить)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
oktonion
Постоялец

ru
Offline Offline

« Ответ #7 : 10-11-2011 11:11 » 

ну в
Код: (C)
VOID WrtFile(UNICODE_STRING nFile, PVOID str)
о типе ничего не известно, так что стоит проверить оба варианта по-моему.

Цитата
и не соображу с ходу - это вообще будет работать? с какой стороны там ноль в юникоде может появится...
с сhar работает точно.
upd:
с WCHAR пишет только первый символ правда размер строки возвращает из RtlStringCchLengthA, если же принудительно заставить его использовать  RtlStringCchLengthW, то пишет полную ахинею - у меня из строки L"Test WCHAR" он записал в файл T e s t. Здесь была моя ладья...
Вместо 100 они там советуют
Цитата
The maximum number of characters allowed in the buffer pointed to by psz, including the terminating NULL character. This value cannot exceed NTSTRSAFE_MAX_CCH.

« Последнее редактирование: 10-11-2011 11:39 от oktonion » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 10-11-2011 11:43 » 

поэтому и используют структуры:
PANSI_STRING
PUNICODE_STRING
 + допонительная инфа о максимальном размере буфера.

PS
Цитата
RtlStringCchLengthW, то пишет полную ахинею - у меня из строки L"Test WCHAR" он записал в файл T e s t.
- а что должно было быть?)
« Последнее редактирование: 10-11-2011 11:46 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
oktonion
Постоялец

ru
Offline Offline

« Ответ #9 : 10-11-2011 12:08 » 

Цитата
Remarks

RtlStringCchLengthW and RtlStringCchLengthA should be used instead of strlen. They are used to ensure that a string is not larger than a given length, in characters. If that condition is met, RtlStringCchLengthW and RtlStringCchLengthA return the current length of the string in characters, not including the terminating NULL character.

Use RtlStringCchLengthW to handle Unicode strings and RtlStringCchLengthA to handle ANSI strings. The form you use depends on your data, as shown in the following table.
String data type      String literal               Function

WCHAR                     L"string"                 RtlStringCchLengthW

char                          "string"                   RtlStringCchLengthA


Вот у меня L"string" , должен записать строку целиком, разве нет? (чувствую опять где то туплю)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 10-11-2011 13:54 » 

вообще то да...
я никогда не ковырялся.. мож принудительно ноль в конце строки забить?)
 L"Test WCHAR\0"
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
oktonion
Постоялец

ru
Offline Offline

« Ответ #11 : 10-11-2011 18:03 » 

Все равно пишет до первого пробела.То есть записывает просто Test.
Интересно, а отличить WCHAR от char вообще реально?
Нам передается некий PVOID в котором либо WCHAR либо char (другие варианты ZwWriteFile не устраивают?), и как различить что там нам передали?
« Последнее редактирование: 10-11-2011 18:06 от oktonion » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 10-11-2011 21:03 » 

гарантированно отличить - думаю невозможно. надо знать заранее.
ноль может быть как концом строки char, так и старшим байтом wchar.
плюс wchar не обязательно с нулем в старшем байте будет.

ересь какая то... попробуйте строку изменить. что нибудь более длинное из нескольких слов. мож он не в байтах выдает а в символах...хотя в ddk четко указано что в байтах...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
oktonion
Постоялец

ru
Offline Offline

« Ответ #13 : 10-11-2011 21:34 » 

В символах, в символах.Я уже понял в чем была загвоздка, ф-я с байтами это не RtlStringCсрLengthA, а RtlStringCbLengthA.Синтаксис один - названия немного разные. Улыбаюсь

И "раз пошла такая пьянка" есть еще 1 вопрос:
Ради чего ZwWriteFile кушает PVOID?Тоесть почему PVOID, если фактически ей можно передать только WCHAR и char, чтобы не словить бсод?Или ей можно передать и int например?
« Последнее редактирование: 10-11-2011 21:42 от oktonion » Записан
zubr
Гость
« Ответ #14 : 11-11-2011 06:01 » 

В символах, в символах.Я уже понял в чем была загвоздка, ф-я с байтами это не RtlStringCсрLengthA, а RtlStringCbLengthA.Синтаксис один - названия немного разные. Улыбаюсь

И "раз пошла такая пьянка" есть еще 1 вопрос:
Ради чего ZwWriteFile кушает PVOID?Тоесть почему PVOID, если фактически ей можно передать только WCHAR и char, чтобы не словить бсод?Или ей можно передать и int например?
Наверно потому, что предполагается, что не только символьные данные могут записываться в файл.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 11-11-2011 07:36 » new

RtlStringCсрLength/RtlStringCbLength - эт я тоже просмотрел)))

Ради чего ZwWriteFile кушает PVOID?Тоесть почему PVOID, если фактически ей можно передать только WCHAR и char, чтобы не словить бсод?Или ей можно передать и int например?
что значит только char? а кто мне мешает массив int-ов записать?) или любую мной выдуманную стркутуру?
функции пофиг на содержание, лишь бы указатель на память был бы верен, и длина не выходила за пределы выделенной памяти.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
oktonion
Постоялец

ru
Offline Offline

« Ответ #16 : 12-11-2011 12:41 » 

Код: (C)
int str = 10;
sizeOfStr = sizeof(int);
if(opn == STATUS_SUCCESS)
  {
        wrt = ZwWriteFile(
                          hFile,
                          0,
                          NULL,
                          NULL,
                          &isb,
                          str,
                          sizeOfStr,
                          NULL,
                          NULL
                         );
  }
как-то так?
или там надо размер ставить количество цифр*sizeof(int)?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 12-11-2011 13:11 » 

почти.
но для ясности:
Код: (C)
int buff_size = 1000;
PVOID buff = ExAllocatePool(NonPagedPool, buff_size);
//проверка buff != 0
...
//заполняем
for(int i=0; i<buff_size/sizeof(int); i++)
{
  ((int*)buff)[i] = i;
}
...
        wrt = ZwWriteFile(
                          hFile,
                          0,
                          NULL,
                          NULL,
                          &isb,
                          buff,
                          buff_size,
                          NULL,
                          NULL
                         );
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines