Игорь98
Новенький
Offline
|
|
« : 25-10-2011 11:18 » |
|
Всем привет. Необходимо что бы драйвер записывал данные в файл. Записывать то он записывает , но вот записывает непонятно что в общем кракозябы какие то. Думаю в чем то ошибся. Вот сама функция которая пишет: 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"); } } А вот кусок кода ее вызова из другой функции: //....... p = (PVOID)ExAllocatePool(PagedPool, cd); if(p) { DbgPrint("ExAllocatePool...YES"); } else { DbgPrint("ExAllocatePool...NO"); } //....... WrtFile(nFile, p); ExFreePool(p); //....... Передача данных из функции в функцию происходит без проблем, а вот запись уже немного хандрит
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #1 : 25-10-2011 12:17 » |
|
потому что sizeof(str) == sizeof(PVOID) ==4 неверно. это размер указателя.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
zubr
Гость
|
|
« Ответ #2 : 25-10-2011 12:22 » |
|
А что ты хотел получить? Ты в файл записываешь не буфер, а указатель на буфер &str и не весь буфер, а размер указателя sizeof(str), для 32-битных систем это 4 байта.
|
|
|
Записан
|
|
|
|
oktonion
Постоялец
Offline
|
|
« Ответ #3 : 08-11-2011 11:16 » |
|
wrt = ZwWriteFile( hFile, 0, NULL, NULL, &isb, str, strlen((char*)str), NULL, NULL );
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #4 : 09-11-2011 12:02 » |
|
не надо так делать: strlen((char*)str)если целью не является собирание всех разнообразных и неожиданных граблей, то для операций со строками в ядре используются Safe String функции... в частности RtlStringCbLength
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
oktonion
Постоялец
Offline
|
|
« Ответ #5 : 10-11-2011 10:08 » |
|
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
|
|
« Ответ #6 : 10-11-2011 10:55 » |
|
угу. правда я не уверен что если RtlStringCchLengthA возвращает STATUS_INVALID_PARAMETER имеет смысл пробовать RtlStringCchLengthW.... тип строки обычно известен заранее) и не соображу с ходу - это вообще будет работать? с какой стороны там ноль в юникоде может появится...
PS и с волшебными числами (типа "100") надо аккуратнее... но это уже в контексте программы лучше дефайнить)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
oktonion
Постоялец
Offline
|
|
« Ответ #7 : 10-11-2011 11:11 » |
|
ну в 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
|
|
« Ответ #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 уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
oktonion
Постоялец
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
|
|
« Ответ #10 : 10-11-2011 13:54 » |
|
вообще то да... я никогда не ковырялся.. мож принудительно ноль в конце строки забить?) L"Test WCHAR\0"
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
oktonion
Постоялец
Offline
|
|
« Ответ #11 : 10-11-2011 18:03 » |
|
Все равно пишет до первого пробела.То есть записывает просто Test. Интересно, а отличить WCHAR от char вообще реально? Нам передается некий PVOID в котором либо WCHAR либо char (другие варианты ZwWriteFile не устраивают?), и как различить что там нам передали?
|
|
« Последнее редактирование: 10-11-2011 18:06 от oktonion »
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #12 : 10-11-2011 21:03 » |
|
гарантированно отличить - думаю невозможно. надо знать заранее. ноль может быть как концом строки char, так и старшим байтом wchar. плюс wchar не обязательно с нулем в старшем байте будет.
ересь какая то... попробуйте строку изменить. что нибудь более длинное из нескольких слов. мож он не в байтах выдает а в символах...хотя в ddk четко указано что в байтах...
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
oktonion
Постоялец
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
|
|
« Ответ #15 : 11-11-2011 07:36 » |
|
RtlStringCсрLength/RtlStringCbLength - эт я тоже просмотрел))) Ради чего ZwWriteFile кушает PVOID?Тоесть почему PVOID, если фактически ей можно передать только WCHAR и char, чтобы не словить бсод?Или ей можно передать и int например?
что значит только char? а кто мне мешает массив int-ов записать?) или любую мной выдуманную стркутуру? функции пофиг на содержание, лишь бы указатель на память был бы верен, и длина не выходила за пределы выделенной памяти.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
oktonion
Постоялец
Offline
|
|
« Ответ #16 : 12-11-2011 12:41 » |
|
int str = 10; sizeOfStr = sizeof(int); if(opn == STATUS_SUCCESS) { wrt = ZwWriteFile( hFile, 0, NULL, NULL, &isb, str, sizeOfStr, NULL, NULL ); } как-то так? или там надо размер ставить количество цифр*sizeof(int)?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #17 : 12-11-2011 13:11 » |
|
почти. но для ясности: 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 уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
|