Reading file names stored in a file.

Hey ,
I am developing a filter driver for tracking changes made in a file.
I stored file names to track in a common file.
I am trying to get file names of registered files through a common file.

I opened common file then I read it with “ZwReadFile” function.
No problem occurred while I opened or read data from it.

Now the problem arise when I am trying to compare it with file name given by IRP->FileObject->fileName and the file name I got from reading the common file.

since the file name given by the IRP->FileObject->fileName is in UNICODE STING.

I tried to use the RtlCompareUnicodeString" function but I cannot get file name from common file in UNICODE STRING format .
I am getting the file name in CHAR buffer[100].

Help Required.

On May 3, 2014, at 11:05 PM, xxxxx@gmail.com wrote:

Now the problem arise when I am trying to compare it with file name given by IRP->FileObject->fileName and the file name I got from reading the common file.

since the file name given by the IRP->FileObject->fileName is in UNICODE STING.

I tried to use the RtlCompareUnicodeString" function but I cannot get file name from common file in UNICODE STRING format .
I am getting the file name in CHAR buffer[100].

And that is the huge mistake in your current design. Your file absolutely needs to be storing Unicode, or at the very least UTF-8. How will you handle a disk with file names in Hungarian and Japanese?

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

You should probably be storing the file names in the common file in WCHAR rather than UCHAR format. Then you don’t have to do any conversion.of character formats.

You can use RtlInitialzeUnicodeString to create a UNICODE_STRING from a WCHAR array.

-p

Sent from my Windows Phone


From: xxxxx@gmail.commailto:xxxxx
Sent: ?5/?3/?2014 11:05 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: [ntdev] Reading file names stored in a file.

Hey ,
I am developing a filter driver for tracking changes made in a file.
I stored file names to track in a common file.
I am trying to get file names of registered files through a common file.

I opened common file then I read it with “ZwReadFile” function.
No problem occurred while I opened or read data from it.

Now the problem arise when I am trying to compare it with file name given by IRP->FileObject->fileName and the file name I got from reading the common file.

since the file name given by the IRP->FileObject->fileName is in UNICODE STING.

I tried to use the RtlCompareUnicodeString" function but I cannot get file name from common file in UNICODE STRING format .
I am getting the file name in CHAR buffer[100].

Help Required.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

Well I had a thought about that also.
But I want user to enter the file name and the same thing will happen to convert the file name to WCHAR format which is not working good for me.

a sample or any pointers will be helpful.
Thanks

You can use RtlAnsiStringToUnicodeString to convert to wide strings.

Sent from my Windows Phone


From: xxxxx@gmail.commailto:xxxxx
Sent: ?5/?4/?2014 7:52 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] Reading file names stored in a file.

Well I had a thought about that also.
But I want user to enter the file name and the same thing will happen to convert the file name to WCHAR format which is not working good for me.

a sample or any pointers will be helpful.
Thanks


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

I had tried RtlAnsiStringToUnicodeString earlier but was facing some problem and it still persists.
This is the code :

PUNICODE_STRING DestinationString=NULL;
char tempBuffer[100];

DbgPrint(“Temp Buffer is::%s\n”, tempBuffer);
ntstatus=RtlAnsiStringToUnicodeString(DestinationString,tempBuffer,TRUE);
if(NT_SUCCESS(ntstatus))
{
RtlInitUnicodeString(&myFileName2, DestinationString);
DbgPrint(“File Read is::%wZ\n”,&myFileName2);
}

I have in tempBuffer my file name fro my common file.
Initially I had not initialized the DestinsationString and it resulted in compiling error.
But now it is compiling yet it gives KERNEL_MODE_EXCEPTION_NOT_HANDLED error in dump file.

Every time I try to install driver it results in crash.
Before I added the RtlInitUnicodeString(&myFileName2, DestinationString); Driver was installing with a success.

The dump File says::

A problem has been detected and Windows has been shut down to prevent damage
to your computer.

The problem seems to be caused by the following file: Filter.sys

KERNEL_MODE_EXCEPTION_NOT_HANDLED

If this is the first time you’ve seen this stop error screen,
restart your computer. If this screen appears again, follow
these steps:

Check to make sure any new hardware or software is properly installed.
If this is a new installation, ask your hardware or software manufacturer
for any Windows updates you might need.

If problems continue, disable or remove any newly installed hardware
or software. Disable BIOS memory options such as caching or shadowing.
If you need to use safe mode to remove or disable components, restart
your computer, press F8 to select Advanced Startup Options, and then
select Safe Mode.

Technical Information:

*** STOP: 0x1000008e (0xc0000005, 0x805d6e25, 0xb282c570, 0x00000000)

*** Filter.sys - Address 0xf89d344c base at 0xf89d2000 DateStamp 0x536726d5

I am curious why you are wasting your time and ours by showing code that
is not the code you are actually using. But the code as shown is buggy
beyond all reason.

RTFM. What are the specs of RtlAnsiStringToUnicodeString?

NTSTATUS RtlAnsiStringToUnicodeString(
Inout PUNICODE_STRING DestinationString,
In PCANSI_STRING SourceString,
In BOOLEAN AllocateDestinationString
);

So, did you give it a valid PUNICODE_STRING for the first parameter?

No, you gave it a NULL pointer!

Why would you create a PUNICODE_STRING variable, set it to NULL, and pass
that NULL in as a valid pointer?

You would declare a variable of type UNICODE_STRING and pass the pointer
to *that*. It is a common beginner error to mistake the specification of
a parameter for a requirement for a variable of that type, but most people
get over this in the first week after pointers are taught. So you should
have declared

UNICODE_STRING DestinationString;

Now, as several people have pointed out, the 8-bit character is dead,
dead, dead (except for debug printouts, and the reasons for that are
probably historical accident). No part of the kernel uses 8-bit strings
for anything. Even lowly NotePad will write Unicode files. In fact, you
should check to see if the files starts with a BOM mark; there are three
of interest: little-endian Unicode (what Windows uses), big-endian Unicode
(which a SparcStation might write, but you could consider it fair to
simply reject as improperly-formatted a big-endian Unicode file, and
UTF-8, which has no endianess and consequently is completely
platform-neutral.

Next, you declare your file name to be a CHAR buffer of size 100. Since
we assume that this filter driver will only be installed on machines with
English-speaking users, we can accept that it is CHAR. But how in the
world did you come up with the totally random number “100”? I don’t know
if the kernel defined a symbol for this, but in user space it is MAX_PATH,
and its value, which you would never use as a string of digits, is 263.
So do you have some reason for working only with files whose names do not
exceed 99, which is considerably less than half of the permissible length?

Also, you do not show how that buffer is initialized; given the other
bugs, it would not surprise me to find that you are doing a strcpy of the
string characters just so you can have them in this buffer. And you do
NOT use strcpy in the kernel, ever. Unless you want to make headlines.
The kind that say “File system product results in successful exploit that
compromised over 300,000 computers in eight hours”. So we need to see
where those bits are coming from and how they get there.

Now, let’s look at the second parameter: PCANSI_STRING. What are you
passing in? tempBuffer. It wants a PCANSI_STRING and you give it a
CHAR*? How did this even compile?

So either this is not the code you used, or you turned off or ignored the
warning messages from the compiler.

Hint: kernel code should compile warning-free. And you should never
compile at less than Warning Level 4, a.k.a. /W4. We can ignore the
(nonexistent) warning level 0, which, if I understand it correctly, can
accept Java, C#, and FORTRAN source files and not give any warnings. The
first real level /W1, is almost as lenient, but will issue warnings for
FORTRAN (but will not issue warnings about COBOL source). /W3, which is
the default, is felt by many to be far too close to /W0 to be trusted.

Surprisingly, there is an actual link to the ANSI_STRING documentation.
Or, not surprising; what is surprising is that you did not follow it and
discover:

typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} ANSI_STRING, *PANSI_STRING;

I think it should be obvious why passing a CHAR* to a function that
expects to find this structure will give you access faults. What you
should have declared was

ANSI_STRING tempBuffer.

So, *after* you have initialized the ANSI_STRING tempBuffer (even the name
scares me, because if you have a table of filenames, there is no need for
a temporary buffer for any purpose whatsoever), your call would be

ntstatus = RtlAnsiStringToUnicodeString(&DestinationString, &tempBuffer,
TRUE);

Now, since you have created this Unicode string, you have to make sure
that you properly free the allocated buffer when you are finished with it.
I do not see that happening in the code that is shown.

Oh, yes, why do you call RtlInitUnicodeString at all? If you wanted the
string in myFileName2, why didn’t you pass &myFileName2 in as the
parameter to RtlAnsiStringToUnicodeString.

So, while we’re at it, let’s look at the parameters to RtlInitUnicodeString:

VOID RtlInitUnicodeString(
Out PUNICODE_STRING DestinationString,
In_opt PCWSTR SourceString
);

So the first parameter is the expected PUNICODE_STRING. But the second
parameter is a pointer to a PCWSTR. You gave it a PUNICODE_STRING so it
could not have possibly compiled without errors. Didn’t this failure to
compile give you a clue? But even if you had specified the correct
address, that is, DestinationString.Buffer, this is a UNICODE_STRING. A
UNICODE_STRING is not guaranteed to end with a NUL character (NULL is a
pointer; NUL is the name of the character whose value is 0). Since
RtlInitUnicodeString requires a terminating NUL, and
RtlAnsiStringToUnicodeString most explicitly does NOT say that the .Buffer
member of the result UNICODE_STRING is NUL-terminated, this code is not
guaranteed to work.

So what is the real code you used, and does it compile warning-free at /W4?

p.s. check RtlFreeUnicodeString, as mentioned in the documentation for
RtlAnsiStringToUnicodeString. Show us where you call it.

None of this is Deep Kernel Magic. All of it is elementary C programming
and knowing how to read documentation. Everything you needed to know was
right in the documentation. As a C programmer, it should have been easy
to understand. And if you are not an experienced C programmer, playing in
the kernel is like juggling live hand grenades. The outcome is
inevitable.
joe

I had tried RtlAnsiStringToUnicodeString earlier but was facing some
problem and it still persists.
This is the code :

PUNICODE_STRING DestinationString=NULL;
char tempBuffer[100];

DbgPrint(“Temp Buffer is::%s\n”, tempBuffer);
ntstatus=RtlAnsiStringToUnicodeString(DestinationString,tempBuffer,TRUE);
if(NT_SUCCESS(ntstatus))
{
RtlInitUnicodeString(&myFileName2, DestinationString);
DbgPrint(“File Read is::%wZ\n”,&myFileName2);
}

I have in tempBuffer my file name fro my common file.

But how did it get there? Why do you not show this code?

Initially I had not initialized the DestinsationString and it resulted in
compiling error.

well, yes. But why was it not obvious to you that passing a NULL pointer
as an argument to where an actual pointer to a real data object is
expected will cause the kernel to crash? The compiler said “If you walk
down this path, you will fall into an open manhole”, and you responded by
cutting a manhole cover out of paper and painting it to look like metal,
so that annoying compiler would stop nagging you. Now you can walk down
the street, texting your friends, and not notice any open manholes. Until
you step on the fake paper cover you taped to the hole. But, hey, at
least the compiler shut up. I’m more concerned with the reasons your
horrific type mismatches on the parameters passed all the tests. The code
you show could not possibly compile without warnings or errors.

The failure to run !analyze -v and include the output makes it difficult
to point out to you how to analyze what went wrong, so you could correct
it.

But now it is compiling yet it gives KERNEL_MODE_EXCEPTION_NOT_HANDLED
error in dump file.

Every time I try to install driver it results in crash.
Before I added the RtlInitUnicodeString(&myFileName2, DestinationString);
Driver was installing with a success.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> Well I had a thought about that also.

But I want user to enter the file name and the same thing will happen to
convert the file name to WCHAR format which is not working good for me.

How is the user typing the file name? Into a GUI-based program? They are
all, by default, Unicode-based, unless you work really hard to make them
punched-card compatible. So there is no reason to convert what the user
types to Unicode; it is already Unicode!

And, as I pointed out, if you are using NotePad, it already supports Unicode.

You can’t claim that it is “hard” to create a Unicode text file in 2014.
It is much harder to produce an 8-bit character file, except for UTF-8
encoding, which is trivial.
joe

a sample or any pointers will be helpful.
Thanks


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

I am getting names of the file through an interface which is writing into a
REGISTERED file.
Interface is a simple c program which adds the file names after verifying
that the file exists.
I got a lot of errors in my code earlier but all of them were not my final
and also it was my fault to give some part of the code which was necessary
at that time.
I am reading by using ZwReadFile function after opening it.
The data read was stored in a buffer and I copied only one line from the
buffer which mean one file name.
Since ZwReadFile function copies the data of buffer length to the buffer I
want to get only one file name at once and that I copied in tempBuffer
char array now I want it to compare with the file name given by the IRP.

To compare I wanted to convert it to UNICODE string .(The part where I am
failing.)

On Mon, May 5, 2014 at 4:53 PM, wrote:

> > Well I had a thought about that also.
> > But I want user to enter the file name and the same thing will happen to
> > convert the file name to WCHAR format which is not working good for me.
>
> How is the user typing the file name? Into a GUI-based program? They are
> all, by default, Unicode-based, unless you work really hard to make them
> punched-card compatible. So there is no reason to convert what the user
> types to Unicode; it is already Unicode!
>
> And, as I pointed out, if you are using NotePad, it already supports
> Unicode.
>
> You can’t claim that it is “hard” to create a Unicode text file in 2014.
> It is much harder to produce an 8-bit character file, except for UTF-8
> encoding, which is trivial.
> joe
> >
> > a sample or any pointers will be helpful.
> > Thanks
> >
> > —
> > NTDEV is sponsored by OSR
> >
> > Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
> >
> > OSR is HIRING!! See http://www.osr.com/careers
> >
> > For our schedule of WDF, WDM, debugging and other seminars visit:
> > http://www.osr.com/seminars
> >
> > To unsubscribe, visit the List Server section of OSR Online at
> > http://www.osronline.com/page.cfm?name=ListServer
> >
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Arvind Jakhar wrote:

I am getting names of the file through an interface which is writing
into a REGISTERED file.

I don’t know what you mean by “registered”.

Interface is a simple c program which adds the file names after
verifying that the file exists.
I got a lot of errors in my code earlier but all of them were not my
final and also it was my fault to give some part of the code which was
necessary at that time.
I am reading by using ZwReadFile function after opening it.
The data read was stored in a buffer and I copied only one line from
the buffer which mean one file name.
Since ZwReadFile function copies the data of buffer length to the
buffer I want to get only one file name at once and that I copied in
tempBuffer char array now I want it to compare with the file name
given by the IRP.

To compare I wanted to convert it to UNICODE string .(The part where I
am failing.)

If you know that the file names will only use characters from the first
128 ASCII set (that is, if you make an “American” assumption), then you
can convert the Unicode to 8-bit yourself by truncating the high byte.

If you don’t know that, then you are screwed. There IS NO SOLUTION.
You don’t know what character set your “simple C program” used to send
the characters, so you cannot possibly know what Unicode code points
those bytes map to. You can’t compare the strings.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

There is no such thing as a “registered” file in Windows, so your forceful
use of the term is nonsensical. You could have said “…into a PURPLE
file” and it would make as much sense.

When you come to a forum and ask for a solution, and everyone says “Don’t
Do That!”, you should take that advice. Just because YOU have never seen
a file name with Unicode characters, does not mean that they don’t exist;
it merely points out your lack of experience. Put the file of names in
Unicode. This makes your problem disappear, which should be your real
goal. Make the input file be in Unicode, and you can be guaranteed that
you will NEVER have a problem. Leave it in 8-bit characters and it is
only a question of “when”, not “if” you will have a failure. Robust
programming has the goal of eliminating problems; you seem to be insisting
that we explain how a BAD (Broken As Designed) solution can be hacked to
work in an uninteresting special case, but fail in all other cases.

It should take you about ten seconds to use NotePad to read in your 8-bit
file and write out a Unicode file. Problem solved. No code is required.
It will work everywhere, for everyone.

Don’t forget about the [optional] BOM (Byte Order Mark) that may be at the
start of the file.

You want a solution. I and a number of others have given the only
solution we know will work in all cases. Ignore this advice at your own
peril.
Joe

Arvind Jakhar wrote:
> I am getting names of the file through an interface which is writing
> into a REGISTERED file.

I don’t know what you mean by “registered”.

> Interface is a simple c program which adds the file names after
> verifying that the file exists.
> I got a lot of errors in my code earlier but all of them were not my
> final and also it was my fault to give some part of the code which was
> necessary at that time.
> I am reading by using ZwReadFile function after opening it.
> The data read was stored in a buffer and I copied only one line from
> the buffer which mean one file name.
> Since ZwReadFile function copies the data of buffer length to the
> buffer I want to get only one file name at once and that I copied in
> tempBuffer char array now I want it to compare with the file name
> given by the IRP.
>
> To compare I wanted to convert it to UNICODE string .(The part where I
> am failing.)

If you know that the file names will only use characters from the first
128 ASCII set (that is, if you make an “American” assumption), then you
can convert the Unicode to 8-bit yourself by truncating the high byte.

If you don’t know that, then you are screwed. There IS NO SOLUTION.
You don’t know what character set your “simple C program” used to send
the characters, so you cannot possibly know what Unicode code points
those bytes map to. You can’t compare the strings.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Since you have not shown any use of ZwReadFile, nor shown any code that
shows how you copy the file names put of the buffer, it is nearly
impossible to tell you what to do, whether the file is 8-bit or Unicode.

I’ve already commented on the foolish use of 8-bit characters and the
concept of “registered” file, a meaningless term.

I had expected that you had a file with multiple file names in it. I
would like to point out that the use of “trmpBuffer” and
“RtlInitUnicodeString” are syntactic noise, since both are completely
unnecessary. Some relevant questions apply here; for example, what is the
greatest number of file names you expect to have the file contain?

In general, what I would do is read the entire file into a single block of
memory. I would compute the offset (in Unicode characters) of the first
file name: 0 if there is no BOM, 1 if there is a BOM. Then I’d scan
forward, by characters, until I hit a carriage return (0x0D), new line
(0x0A), or reached the last character in the file (you cannot assume the
last line in the file has a CRLF. Now you have a buffer pointer and a
length. You use these to initialize a UNICODE_STRING. Skip over any CR
or LF until you find a non-CR, non-LF character (you may also want to skip
over any spaces or tabs as well. Now you have a new starting position.
Lather, rinse, repeat. Note that at no time is a copy operation
performed. Just hang onto the buffer until you no longer need the file
names. No tempBuffer, no copies, always works everywhere. What’s not to
like?
joe

I am getting names of the file through an interface which is writing into
a
REGISTERED file.
Interface is a simple c program which adds the file names after verifying
that the file exists.
I got a lot of errors in my code earlier but all of them were not my final
and also it was my fault to give some part of the code which was necessary
at that time.
I am reading by using ZwReadFile function after opening it.
The data read was stored in a buffer and I copied only one line from the
buffer which mean one file name.
Since ZwReadFile function copies the data of buffer length to the buffer I
want to get only one file name at once and that I copied in tempBuffer
char array now I want it to compare with the file name given by the IRP.

To compare I wanted to convert it to UNICODE string .(The part where I am
failing.)

On Mon, May 5, 2014 at 4:53 PM, wrote:
>
>> > Well I had a thought about that also.
>> > But I want user to enter the file name and the same thing will happen
>> to
>> > convert the file name to WCHAR format which is not working good for
>> me.
>>
>> How is the user typing the file name? Into a GUI-based program? They
>> are
>> all, by default, Unicode-based, unless you work really hard to make them
>> punched-card compatible. So there is no reason to convert what the user
>> types to Unicode; it is already Unicode!
>>
>> And, as I pointed out, if you are using NotePad, it already supports
>> Unicode.
>>
>> You can’t claim that it is “hard” to create a Unicode text file in 2014.
>> It is much harder to produce an 8-bit character file, except for UTF-8
>> encoding, which is trivial.
>> joe
>> >
>> > a sample or any pointers will be helpful.
>> > Thanks
>> >
>> > —
>> > NTDEV is sponsored by OSR
>> >
>> > Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>> >
>> > OSR is HIRING!! See http://www.osr.com/careers
>> >
>> > For our schedule of WDF, WDM, debugging and other seminars visit:
>> > http://www.osr.com/seminars
>> >
>> > To unsubscribe, visit the List Server section of OSR Online at
>> > http://www.osronline.com/page.cfm?name=ListServer
>> >
>>
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>>
>> OSR is HIRING!! See http://www.osr.com/careers
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

and here is a DEBUG AID sample that almost illustrates what Dr
NewComer posted in an earlier post

the driver compiled with code below takes an ANSI .txt file with several lines
reads the first N Lines ( bytes < =200) and prints out N - X ( bytes
<100 ) lines

use only for grasping the concept do not to copy paste especially
gotos are frowned upon so be aware .

code as folllws

#define NTSTRSAFE_LIB
#include <wdm.h>
#include <ntstrsafe.h>

#define SIZE_XXXL 1024
#define SIZE_XXL SIZE_XXXL/2
#define SIZE_XL SIZE_XXL/2

DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD DriverUnload;

void DriverUnload( PDRIVER_OBJECT DriverObject ) {
UNREFERENCED_PARAMETER(DriverObject);
DbgPrint(“Driver unloading\n”);
}

NTSTATUS DriverEntry( in PDRIVER_OBJECT DriverObject, in
PUNICODE_STRING RegistryPath ) {

HANDLE FileHandle = NULL;
PCHAR ReadBuffer = NULL;
PCHAR tmpbuffer = NULL;
int i = 0;
int j = 0;
NTSTATUS status = STATUS_SUCCESS;

UNICODE_STRING FileName;
IO_STATUS_BLOCK CreateIosb;
IO_STATUS_BLOCK ReadIosb;
ANSI_STRING SrcStr;
UNICODE_STRING DestStr;
OBJECT_ATTRIBUTES oa;
LARGE_INTEGER ByteOffset;
FILE_STANDARD_INFORMATION Fileinfo;

UNREFERENCED_PARAMETER(DriverObject);
UNREFERENCED_PARAMETER(RegistryPath);

DbgPrint (“\nZero out all the structs start with a clean slate \n” );
RtlZeroMemory(&FileName,sizeof(UNICODE_STRING));
RtlZeroMemory(&CreateIosb,sizeof(IO_STATUS_BLOCK));
RtlZeroMemory(&ReadIosb,sizeof(IO_STATUS_BLOCK));
RtlZeroMemory(&SrcStr,sizeof(ANSI_STRING));
RtlZeroMemory(&DestStr,sizeof(UNICODE_STRING));
RtlZeroMemory(&oa,sizeof(OBJECT_ATTRIBUTES));
RtlZeroMemory(&ByteOffset,sizeof(LARGE_INTEGER));
RtlZeroMemory(&Fileinfo,sizeof(FILE_STANDARD_INFORMATION));

DbgPrint (“starting with a clean slate check in windbg for
confirmation\n” );

DbgPrint(" initializing the FileOffset setting 0 in (
LARGE_INTEGER ) ByteOffset\n");
ByteOffset.HighPart = 0;
ByteOffset.LowPart = 0;

DriverObject->DriverUnload = DriverUnload;
DbgPrint(“Driver Entry\n”);

DbgPrint(“allocating 2 buffers in non paged pool one for ReadFile
and one for RtlAnsiToUni ANSI_STRING\n”);

ReadBuffer = ( PCHAR ) ExAllocatePoolWithTag(NonPagedPool,SIZE_XXXL,‘1nuP’);
tmpbuffer = ( PCHAR ) ExAllocatePoolWithTag(NonPagedPool,SIZE_XXL,‘1nuP’);

DbgPrint(“confirming Allocation will exit here on failure \n”);

if ( ( ReadBuffer == NULL) && ( tmpbuffer == NULL) ) {
DbgPrint(“ExAllocatePoolWithTag Failed ReadBuffer = %p\n
tmpbuffer = %p\n”,ReadBuffer,tmpbuffer);
status = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}

DbgPrint(“ExAllocatePoolWihtTag succeded\nReadBuffer =
%p\ntmpbuffer = %p\n”,ReadBuffer,tmpbuffer);

RtlInitUnicodeString(&FileName,L"\??\c:\myfile.txt");

DbgPrint(“writing from UNICODE_STRING FileName.Buffer %ws and
Intialising Object Attrs\n” , FileName.Buffer );

InitializeObjectAttributes(&oa,&FileName,OBJ_CASE_INSENSITIVE,NULL,NULL);

DbgPrint (“calling ZwCreatefile for reading an existing file\n”);

status = ZwCreateFile(
&FileHandle,
GENERIC_READ,
&oa,
&CreateIosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE,
NULL,
0
);

DbgPrint(“exits here on failure CreateIosb.Information holds %x\n”
,CreateIosb.Information );

if (! NT_SUCCESS(status)) {
DbgPrint(“ZwCreateFile Failed status = %x\n”,status);
status = STATUS_NO_SUCH_FILE;
goto exit;
}

DbgPrint("ZwCreateFile succeded status = %x onto read the ANSI
file Handle %x\n ",status,FileHandle);

status = ZwReadFile(
FileHandle,
NULL,
NULL,
NULL,
&ReadIosb,
ReadBuffer,
SIZE_XXL,
&ByteOffset,
NULL
);

DbgPrint(“exits here on failure ReadIosb.Information holds bytes
read from file = %x\n” ,ReadIosb.Information );

if ( ! NT_SUCCESS(status)) {
DbgPrint(“ZwReadFile Failed status = %x\n”,status);
status = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
DbgPrint(“ZwReadFile succeded status = %x getting filesize\n”,status);

status = ZwQueryInformationFile(
FileHandle,
&CreateIosb,
&Fileinfo,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation
);
if ( ! NT_SUCCESS(status)) {
DbgPrint(“ZwQueryInformationFile Failed status = %x\n”,status);
status = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
DbgPrint( “file size = %x\n” , Fileinfo.EndOfFile.LowPart);

i = 0;
redo:
while ( ((ReadBuffer+i) != 0x0d ) && ((ReadBuffer+i+1) != 0x0a ) )
{
i++;
}

RtlStringCbCopyNA(tmpbuffer,SIZE_XXL,ReadBuffer+j,i-j);

RtlInitAnsiString(&SrcStr,tmpbuffer);

RtlAnsiStringToUnicodeString(&DestStr,&SrcStr,TRUE);

DbgPrint( “%ws\n”,DestStr.Buffer);
if ( i < SIZE_XL-20)
{
i = i+2;
j = i;
goto redo;
}
else
{
status = STATUS_SUCCESS;
goto exit;
}
exit:
if(ReadBuffer)
ExFreePool(ReadBuffer);
if(tmpbuffer)
ExFreePool(tmpbuffer);
if(FileHandle)
ZwClose(FileHandle);
if( DestStr.Buffer != NULL)
RtlFreeUnicodeString(&DestStr);
return status;
}

contents of sources file to build

TARGETNAME=punicode
CDEFINES=-P
TARGETTYPE=DRIVER
TARGETPATH=obj
SOURCES = punicode.c
TARGETLIBS=C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib
MSC_WARNING_LEVEL=-W4 -WX

Driver Loaded with osrloader in a vm
verifier all tests enabled for driver

output of the driver

*******************************************************************************

This is the string you add to your checkin description
* Driver Verifier: Enabled for p
Zero out all the structs start with a clean slate
starting with a clean slate check in windbg for confirmation
initializing the FileOffset setting 0 in ( LARGE_INTEGER ) ByteOffset
Driver Entry
allocating 2 buffers in non paged pool one for ReadFile and one for
RtlAnsiToUni ANSI_STRING
confirming Allocation will exit here on failure
ExAllocatePoolWihtTag succeded
ReadBuffer = 81748C00
tmpbuffer = 81992E00
writing from UNICODE_STRING FileName.Buffer ??\c:\myfile.txt and
Intialising Object Attrs
calling ZwCreatefile for reading an existing file
exits here on failure CreateIosb.Information holds 1
ZwCreateFile succeded status = 0 onto read the ANSI file Handle 4cc
exits here on failure ReadIosb.Information holds bytes read from file = 200
ZwReadFile succeded status = 0 getting filesize
file size = 250
test line1
test line2
test line3
test line4
this is a test file
file saved as ansi not unicode no fffe marker
at the start of file
this is the end of the content
garbage to bloat filesize > 0x200 follows
u
uu
uuu
uuuu
uuuuuuuuuu
Driver unloading

Break instruction exception - code 80000003 (first chance)

kd> !verifier

Verify Level ff … enabled options are:
Special pool
Special irql
Inject random low-resource API failures
All pool allocations checked on unload
Io subsystem checking enabled
Deadlock detection enabled
Enhanced Io checking enabled
DMA checking enabled

Summary of All Verifier Statistics

RaiseIrqls 0x0
AcquireSpinLocks 0x0
Synch Executions 0x0
Trims 0x0

Pool Allocations Attempted 0x40
Pool Allocations Succeeded 0x40
Pool Allocations Succeeded SpecialPool 0x40
Pool Allocations With NO TAG 0x0
Pool Allocations Failed 0x0
Resource Allocations Failed Deliberately 0x0

Current paged pool allocations 0x0 for 00000000 bytes
Peak paged pool allocations 0x0 for 00000000 bytes
Current nonpaged pool allocations 0x0 for 00000000 bytes
Peak nonpaged pool allocations 0x2 for 00000600 bytes

On 5/7/14, xxxxx@flounder.com wrote:
> Since you have not shown any use of ZwReadFile, nor shown any code that
> shows how you copy the file names put of the buffer, it is nearly
> impossible to tell you what to do, whether the file is 8-bit or Unicode.
>
> I’ve already commented on the foolish use of 8-bit characters and the
> concept of “registered” file, a meaningless term.
>
> I had expected that you had a file with multiple file names in it. I
> would like to point out that the use of “trmpBuffer” and
> “RtlInitUnicodeString” are syntactic noise, since both are completely
> unnecessary. Some relevant questions apply here; for example, what is the
> greatest number of file names you expect to have the file contain?
>
> In general, what I would do is read the entire file into a single block of
> memory. I would compute the offset (in Unicode characters) of the first
> file name: 0 if there is no BOM, 1 if there is a BOM. Then I’d scan
> forward, by characters, until I hit a carriage return (0x0D), new line
> (0x0A), or reached the last character in the file (you cannot assume the
> last line in the file has a CRLF. Now you have a buffer pointer and a
> length. You use these to initialize a UNICODE_STRING. Skip over any CR
> or LF until you find a non-CR, non-LF character (you may also want to skip
> over any spaces or tabs as well. Now you have a new starting position.
> Lather, rinse, repeat. Note that at no time is a copy operation
> performed. Just hang onto the buffer until you no longer need the file
> names. No tempBuffer, no copies, always works everywhere. What’s not to
> like?
> joe
>
> > I am getting names of the file through an interface which is writing
> into
>> a
>> REGISTERED file.
>> Interface is a simple c program which adds the file names after verifying
>> that the file exists.
>> I got a lot of errors in my code earlier but all of them were not my
>> final
>> and also it was my fault to give some part of the code which was
>> necessary
>> at that time.
>> I am reading by using ZwReadFile function after opening it.
>> The data read was stored in a buffer and I copied only one line from the
>> buffer which mean one file name.
>> Since ZwReadFile function copies the data of buffer length to the buffer
>> I
>> want to get only one file name at once and that I copied in tempBuffer
>> char array now I want it to compare with the file name given by the IRP.
>>
>> To compare I wanted to convert it to UNICODE string .(The part where I am
>> failing.)
>>
>>
>> On Mon, May 5, 2014 at 4:53 PM, wrote:
>>
>>> > Well I had a thought about that also.
>>> > But I want user to enter the file name and the same thing will happen
>>> to
>>> > convert the file name to WCHAR format which is not working good for
>>> me.
>>>
>>> How is the user typing the file name? Into a GUI-based program? They
>>> are
>>> all, by default, Unicode-based, unless you work really hard to make them
>>> punched-card compatible. So there is no reason to convert what the user
>>> types to Unicode; it is already Unicode!
>>>
>>> And, as I pointed out, if you are using NotePad, it already supports
>>> Unicode.
>>>
>>> You can’t claim that it is “hard” to create a Unicode text file in 2014.
>>> It is much harder to produce an 8-bit character file, except for UTF-8
>>> encoding, which is trivial.
>>> joe
>>> >
>>> > a sample or any pointers will be helpful.
>>> > Thanks
>>> >
>>> > —
>>> > NTDEV is sponsored by OSR
>>> >
>>> > Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>>> >
>>> > OSR is HIRING!! See http://www.osr.com/careers
>>> >
>>> > For our schedule of WDF, WDM, debugging and other seminars visit:
>>> > http://www.osr.com/seminars
>>> >
>>> > To unsubscribe, visit the List Server section of OSR Online at
>>> > http://www.osronline.com/page.cfm?name=ListServer
>>> >
>>>
>>>
>>>
>>> —
>>> NTDEV is sponsored by OSR
>>>
>>> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>>>
>>> OSR is HIRING!! See http://www.osr.com/careers
>>>
>>> For our schedule of WDF, WDM, debugging and other seminars visit:
>>> http://www.osr.com/seminars
>>>
>>> To unsubscribe, visit the List Server section of OSR Online at
>>> http://www.osronline.com/page.cfm?name=ListServer
>>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>>
>> OSR is HIRING!! See http://www.osr.com/careers
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
></ntstrsafe.h></wdm.h>

Sorry for replying so late .

I got my problem thanks to all of you.
Now I am reading file to ANSI_STRING and converting it to UNICODE successfully.

Thanks once again.

Well I want to know that : When any file is written by using notepad and we save it , then whether the whole file is written every time or just the changes are recorded.

I have to find the number of bytes changed and their offset where the changes have occurred.

IrpSp->Parameters.Write.Length :Gives me size of whole file whenever I am changing and saving a .txt file using notepad.

IrpSp->Parameters.Write.ByteOffset.QuadPart: Gives me zero(0) every time irrespective of file size.

Is there any other way which could give me offset of file where changes have been done now.

Thanks in advance.

Notepad (and pretty much every document editor) writes the whole file anew.

So there is no way I would find out the offset of new written data.

xxxxx@gmail.com wrote:

So there is no way I would find out the offset of new written data.

So, if the user loads a file into Notepad, inserts one character, and
writes out the result, you want to know which character changed?

No. That’s impossible. You aren’t thinking about what you’re asking.
For the first write, you might be able to go fetch the old contents and
do a byte-by-byte comparison, but that would be stupid. And as soon as
he writes the first buffer, the end of file marker moves and the
remaining sectors are freed.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> Well I want to know that : When any file is written by using notepad and we save it , then whether the

whole file is written every time or just the changes are recorded.

I don’t think NOTEPAD can update the separate ranges in the file.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com