Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Need help with ZwCreateFile()

1,078 views
Skip to first unread message

Rich Warner

unread,
Feb 10, 2001, 12:24:03 AM2/10/01
to
ZwCreateFile() is always returning STATUS_OBJECT_PATH_NOT_FOUND even though
I'm using a (I think) fully qualified filename, e.g.
L"\\??\\C:\\Windows\\Temp\\AFile.txt" via a properly buffered
UNICODE_STRING.

Can anyone illuminate the error of my ways?

NTSTATUS OpenAFile( PHANDLE pFileHandle, PUNICODE_STRING wszName, BOOLEAN
bCreate )
{
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK iosb;
NTSTATUS ntStatus;

RtlZeroMemory( &oa, sizeof(OBJECT_ATTRIBUTES) );
RtlZeroMemory( &iosb, sizeof(IO_STATUS_BLOCK) );

oa.Length = sizeof(OBJECT_ATTRIBUTES);
oa.RootDirectory = NULL;
oa.ObjectName = wszName;
oa.Attributes = OBJ_CASE_INSENSITIVE;
oa.SecurityDescriptor = NULL;
oa.SecurityQualityOfService = NULL;

ntStatus = ZwCreateFile( pFileHandle,
GENERIC_READ | GENERIC_WRITE,
&oa,
&iosb,
0,
FILE_ATTRIBUTE_NORMAL,
0,
bCreate ? FILE_OPEN_IF : FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
return( ntStatus );
}


Luc Kumps

unread,
Feb 10, 2001, 3:51:05 AM2/10/01
to
Just guessing, but shouldn't there be 4 '\' signs at the begiining of your
filename?

Luc

"Rich Warner" <rwa...@aol.com> wrote in message
news:uLc5wHykAHA.1424@tkmsftngp03...

Rich Warner

unread,
Feb 10, 2001, 12:53:36 PM2/10/01
to
"\\\\.\\xxxx" is how you open device xxxx directly from user mode, but I'm
trying to go the opposite way, i.e. open a high level file from within a low
level driver. The form I'm using is described by the DDK docs and is used in
their sample code.

Thanks,
Rich

Luc Kumps <NOkum...@pandora.be> wrote in message
news:Zh7h6.5302$w_6.2...@afrodite.telenet-ops.be...

Carl Woodward

unread,
Feb 10, 2001, 3:01:53 PM2/10/01
to
What is the value of ntStatus?

Carl

--
-


"Rich Warner" <rwa...@aol.com> wrote in message
news:uLc5wHykAHA.1424@tkmsftngp03...

Carl Woodward

unread,
Feb 10, 2001, 3:03:59 PM2/10/01
to
No dont think so, you tend to only use that when attempting to open a
device. Given that Rich is explicitly passing the entire path including ??
the object manager should have no problem parsing it.

Carl

--
-


"Luc Kumps" <NOkum...@pandora.be> wrote in message
news:Zh7h6.5302$w_6.2...@afrodite.telenet-ops.be...

Rich Warner

unread,
Feb 10, 2001, 5:09:04 PM2/10/01
to
Value returned by the function is 0xC000003AL, which ntstatus.h gives the
symbolic label STATUS_OBJECT_PATH_NOT_FOUND

Rich

Carl Woodward <djc2000...@btinternet.com> wrote in message
news:9646vk$7j3$1...@neptunium.btinternet.com...

keithmo

unread,
Feb 11, 2001, 2:29:51 AM2/11/01
to
The path you provided looks fine (assuming the directories & file really
exist). I'd check to ensure the UNICODE_STRING really is properly formatted.
If you're building the UNICODE_STRING manually (not using
RtlInitUnicodeString() or some other API), then check to ensure the Length
and MaximumLength fields are *byte* counts, rather than *character* counts.

You could add:

DbgPrint( "wszName = %wZ\n", wszName );

to sanity check the string.


KM

Luc Kumps

unread,
Feb 11, 2001, 7:57:45 AM2/11/01
to
I tried this on my system (NT 4.0, SP6a), and got it to work, but found a
few errors.

1. I kept getting error c000000d (invalid parameter).
I looked up ZwCreateFile in the docs
(see http://www.microsoft.com/ddk/ddkdocs/win2k/k111_9dte.htm)
It says:
"FILE_SYNCHRONOUS_IO_NONALERT All operations on the file are performed
synchronously. Waits in the system to synchronize I/O queueing and
completion are not subject to alerts. This flag also causes the I/O system
to maintain the file position context. If this flag is set, the
DesiredAccess SYNCHRONIZE flag also must be set."
I added SYNCHRONIZE, and it worked!

2. I'm not sure if the DesiredAccess parameter supports GENERIC_READ. The
value GENERIC_READ is defined as 0x8000000L. But the corresponding value in
the above doc is FILE_READ_DATA, which is defined as 0x0001. GENERIC_WRITE
is 0x40000000, and FILE_WRITE_DATA is 0x0002

Therefore, I would specify
FILE_READ_DATE | FILE_WRITE_DATA | SYNCHRONIZE,
instead of
> GENERIC_READ | GENERIC_WRITE,

Now, you say you get c000003a instead of c000000d...

If you correctly initialized your UNICODE_STRING like this:

NT::UNICODE_STRING us;
NT::RtlInitUnicodeString(&us, L"\\??\\C:\\Windows\\Temp\\AFile.txt");

(and you probably did, otherwise you would get c0000033)
then the only reason I can see is that either c:\Windows and/or
c:\windows\temp do(es) not exist...

Luc

"Rich Warner" <rwa...@aol.com> wrote in message
news:uLc5wHykAHA.1424@tkmsftngp03...

Luc Kumps

unread,
Feb 11, 2001, 8:03:50 AM2/11/01
to
BTW, the Microsoft doc I mentioned *does* say that you can use GENERIC_READ
and GENERIC_WRITE. However, when one looks inside ntddk.h, it seems that
they are talking about FILE_GENERIC_READ and FILE_GENERIC_WRITE...
The values are:
GENERIC_READ = 0x8000000
FILE_GENERIC_READ = 0x120089

Luc

"Luc Kumps" <NOkum...@pandora.be> wrote in message

news:d%vh6.9271$w_6.6...@afrodite.telenet-ops.be...

keithmo

unread,
Feb 11, 2001, 5:53:44 PM2/11/01
to

"Luc Kumps" <NOkum...@pandora.be> wrote in message
news:W4wh6.9281$w_6.6...@afrodite.telenet-ops.be...

> BTW, the Microsoft doc I mentioned *does* say that you can use
GENERIC_READ
> and GENERIC_WRITE. However, when one looks inside ntddk.h, it seems that
> they are talking about FILE_GENERIC_READ and FILE_GENERIC_WRITE...
> The values are:
> GENERIC_READ = 0x8000000
> FILE_GENERIC_READ = 0x120089

The GENERIC_* access masks are "generic" in that they apply to all object
types. At the time the object is opened/created the generic masks are mapped
to the corresponding type-specific masks. So, ZwCreateFile() maps
GENERIC_READ to FILE_GENERIC_READ. Likewise, ZwCreateKey() maps GENERIC_READ
to KEY_READ.


KM


Luc Kumps

unread,
Feb 12, 2001, 3:09:08 AM2/12/01
to
Aha! Thanks for the clarification!

Luc

"keithmo" <kei...@earthlink.SPAM.FREE.net> wrote in message
news:t8e5qfg...@corp.supernews.com...

Rich Warner

unread,
Feb 12, 2001, 9:19:55 AM2/12/01
to
Thanks for the good advice so far. I had eliminated the UNICODE_STRING
questions long before I rasied a plea for help! The state of play now is I
can get a successful open only in \SystemRoot\system32\drivers. Is this for
real? Luc, where was the file that you sccuessfully opened?

Thanks,
Rich


Luc Kumps

unread,
Feb 12, 2001, 10:17:46 AM2/12/01
to

"Rich Warner" <rwa...@aol.com> wrote in message
news:#8aLz8PlAHA.1412@tkmsftngp02...

This works on my system (after creating a \Windows and a \Windows\Temp
directory)

NT::RtlInitUnicodeString(&us, L"\\??\\C:\\Windows\\Temp\\AFile.txt" );
printf("%x\n", OpenAFile(&hFile, &us, TRUE));

(prints a "0", and "AFile.txt" is created)

Full source code below...

Luc


#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
namespace NT {
extern "C" {
#pragma warning(disable: 4005)
#include <ntddk.h>
#pragma warning(default: 4005)
}
};
using NT::NTSTATUS;
NTSTATUS OpenAFile( PHANDLE pFileHandle, NT::PUNICODE_STRING wszName,
BOOLEAN bCreate )
{
NT::OBJECT_ATTRIBUTES oa;
NT::IO_STATUS_BLOCK iosb;
NT::NTSTATUS ntStatus;

RtlZeroMemory( &oa, sizeof(oa) );
RtlZeroMemory( &iosb, sizeof(iosb) );

oa.Length = sizeof(NT::OBJECT_ATTRIBUTES);


oa.RootDirectory = NULL;
oa.ObjectName = wszName;
oa.Attributes = OBJ_CASE_INSENSITIVE;
oa.SecurityDescriptor = NULL;
oa.SecurityQualityOfService = NULL;

ntStatus = NT::ZwCreateFile( pFileHandle,
FILE_GENERIC_READ | FILE_GENERIC_WRITE |
SYNCHRONIZE,


&oa,
&iosb,
0,
FILE_ATTRIBUTE_NORMAL,
0,
bCreate ? FILE_OPEN_IF : FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0 );
return( ntStatus );
}

int main(void) {
HANDLE hFile;
NT::UNICODE_STRING us;
NT::RtlInitUnicodeString(&us, L"\\??\\C:\\Windows\\Temp\\AFile.txt" );
printf("%x\n", OpenAFile(&hFile, &us, TRUE));
return 0;
}

Doug Haigh

unread,
Feb 12, 2001, 11:53:50 AM2/12/01
to
Sounds like you are opeining the file before the file system is loaded. Is
this a boot driver?

"Rich Warner" <rwa...@aol.com> wrote in message
news:#8aLz8PlAHA.1412@tkmsftngp02...

dave porter

unread,
Feb 12, 2001, 12:55:43 PM2/12/01
to
You realise that drive letters don't show up until
quite late in the life of the system (definitely not
before the system can run processes).

You need to use the proper name of the device
before that point, not the DOS-compatibility name.
The proper name will be something like
\Device\Harddisk0\Partition1.

dave
--
To reply by mail, replace 'z' by 's'


"Rich Warner" <rwa...@aol.com> wrote in message

news:uLc5wHykAHA.1424@tkmsftngp03...

Rich Warner

unread,
Feb 12, 2001, 4:29:49 PM2/12/01
to
No, the file name to be opened is IOCTL'ed from a user mode app. The
constant string in my code snippet was just a fallback to be sure the
problem wasn't in parameter passing, unicode conversion, etc.

What I'm up to is porting a Win16 quasi-realtime database server for a data
acquisition application (well logging). It could all be done in a DLL
before! The target OSes are 98 and 2kPro. So far I've only tried on 98.

Thanks... Any more ideas?

Doug Haigh <dha...@junk.com> wrote in message
news:eAeHBSRlAHA.1804@tkmsftngp04...

Doug Haigh

unread,
Feb 12, 2001, 10:05:01 PM2/12/01
to
Win98? Why didn't you say so! Zw*File does not work on Win98 (surprise). You
could buy Walter Oney's Book on the Window's Driver Model or go to his
website (http://www.oneysoft.com) and read his white paper on doing file IO
in WDM drivers(http://www.oneysoft.com/FileIO.zip). VERY helpful. Buy his
book.

Doug

"Rich Warner" <rwa...@aol.com> wrote in message

news:e7ikKtTlAHA.1720@tkmsftngp02...

Luc Kumps

unread,
Feb 13, 2001, 3:40:37 AM2/13/01
to
A user application? Why do you need to use ZwCreateFile instead of
CreateFile?

Luc

"Rich Warner" <rwa...@aol.com> wrote in message

news:e7ikKtTlAHA.1720@tkmsftngp02...

Rich Warner

unread,
Feb 13, 2001, 9:26:17 AM2/13/01
to
Win98 first because its on the laptop that follows me around. I got the idea
to use these functions because they are described in the docs for both 98
and 2k ddks. I was shooting for the lowest common denominator. But I am now
successfully using ZwCreateFile, ZwReadFile, ZwWriteFile and
ZwQueryInformationFile in 98. Using \DosDevices instead of \?? did the
trick. (I had tried that early on but probably had something else messed
up...) The only funky thing now is how to detect a 'file not found'...
ZwCreateFile returns STATUS_ACCESS_DENIED and iosb.Information does NOT have
FILE_DOES_NOT_EXIST.

Thanks to the link to Mr. Oney's site. I already had the book on its way to
me.

Rich

Doug Haigh <dha...@junk.com> wrote in message

news:OJ1wjnWlAHA.1384@tkmsftngp04...

Rich Warner

unread,
Feb 13, 2001, 9:41:56 AM2/13/01
to
This is a multi-process (and will now be multi-machine) data server. There
are several producers and consumers accessing multiple files. The file
structure is n-level indexed and has its own namespace within... not the
sort of thing to replicate into the dozens of apps involved. And record
caching in the server improves performance when several apps are interested
in the same data at the same time.

Rich

Luc Kumps <NOkum...@pandora.be> wrote in message

news:9q6i6.5942$Tu.2...@afrodite.telenet-ops.be...

David Union

unread,
Feb 18, 2001, 2:59:37 PM2/18/01
to
You need the InitializeObjectAttributes() function to init the oa I think.


"Rich Warner" <rwa...@aol.com> wrote in message

news:#bdrlq4kAHA.1324@tkmsftngp05...

0 new messages