Advertisement

CreateFile

Started by September 12, 2000 10:28 PM
4 comments, last by braves 24 years, 3 months ago
Hello everyone, I am new to programming in the Windows API and I have a few questions about the API function CreateFile. It says the parameters are as shown : HANDLE CreateFile( LPCTSTR lpFileName, // file name DWORD dwDesiredAccess, // access mode DWORD dwShareMode, // share mode LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD DWORD dwCreationDisposition, // how to create DWORD dwFlagsAndAttributes, // file attributes HANDLE hTemplateFile // handle to template file ); Now, I have a few questions about these pramaters. 1) It says that parameter 2 can either be 0, GENERIC_READ, GENERIC_WRITE and a few other access flags you can specify which are : DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER, SYNCHRONIZE, STANDARD_RIGHTS_REQUIRED, STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE and others. MSDN says about these : Each type of securable object has a set of access rights that correspond to operations specific to that type of object. In addition to these object-specific access rights, there is a set of standard access rights that correspond to operations common to most types of securable objects. Can someone translate this for me? Another thing with parameters 4 which is the it says lpSecurityAttributes Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpSecurityAttributes is NULL, the handle cannot be inherited. Windows NT/2000: The lpSecurityDescriptor member of the structure specifies a security descriptor for the object. If lpSecurityAttributes is NULL, the object gets a default security descriptor. The target file system must support security on files and directories for this parameter to have an effect on files Can someone explain what it means by inherited from a child process? Does it mean if its a thread from the main thread of the process? Also, how can you tell if your file system supports securit on files and directories? Does that mean if your on client/server and if you have like share access? The last question is about the last parameter. What is a template file? Thanks for everyones time, Braves
Concerning the access flags (parameter 2). These just let CreateFile know how you intend to access the file. Read-only (GENERIC_READ), write-only (GENERIC_WRITE), and read-write(GENERIC_READ | GENERIC_WRITE) are the typical cases people are interested in. The others (e.g. READ_CONTROL) are for special security related stuff mostly and if you don''t know what they are you probably don''t care either. Just stick to the GENERIC_XXX flags.

Concerning the security attributes. Again, security related stuff. 99% of the time you don''t care and just use NULL. The bit about inheriting the handle in a child process means that if your app starts another app (a child process), then if the handle is inheritable, the child process will be able to use it as well as the main process.

A template file can be used when creating a new file. It basically means that you want the new file to be just like the old file. The new file will get the same security settings, etc. Again, you very rarely care.

CreateFile is one of the best(?!) examples of poor API design IMHO. 99% of the time you just want everything to be the default but you still have to go through and put NULL or whatever in all the parameters. It''s usually far simpler to just use the standard C file functions (e.g. fopen) - they work just fine in Windows.

-Mike
Advertisement
Mike:

Yes, it could certainly benefit from function overloading and/or default parameters.

Actually, it's not so bad considering what it does. After all, the standard libs really just call CreateFile internally (that's how the run-time library functions are platform independent - each platform has its own implementation), and all the other associated file functions just call ReadFile, WriteFile, etc. VB probably uses it internally, as do most other languages. Think of the fopen and similar functions as simplified versions that are just fine to use 99% of the time. Besides, they're more portable, because they work the same on every platform, while CreateFile is Win32-only.

In fact the major reason for the poor design of the Win32 API is to remain compatible with as many different languages APIs as possible. To that end, it's not _too_ bad.

BTW, I wonder what a C++ version of the Win32 API would look like? MFC really just wraps the Win32 API (and provides some services besides)...so it's got some quirks of its own.



- null_pointer
Sabre Multimedia


Edited by - null_pointer on September 13, 2000 10:22:49 PM
Thanks guys. I still like to know about the security attributes are for. I am trying to learn about security so I think it would good to understand these attributes for NT. I guess I would look up security in the MSDN to learn about these attributes? When it says security is it talking about the different groups on the server that can access your program or a different type of security? I do have another question. Why does Microsoft like to typedef everything? Like LPSTR which is nothen more than char *. Another thing I get confussed with is stuff like LPTSTR, which it says is A 32-bit pointer to a character string that is portable for Unicode and DBCS. when I put my cursor over LPTSTR it says short *, how can this be a character string? Last time I knew charater strings where char *? How can you put a string into a pointer to a short which would hold numbers not ASCII charaters. Does Unicode and DBCS change the way I should code? Someone told me there is a setting in Visual C++ that affects if your using Unicode or DBCS? Is DBCS just like ASCII? I know this is alot of questions just trying to understand Microsofts way of developing stuff.
Braves

Well, I''m not an expert on this but here goes!

char is just an integer value, from -128 to +127, and unsigned char is a whole number, from 0 to 256. ASCII characters are really just translated into numerical values when you do this:


char my_string[] = "hello world!";



Typically, each character in that string is stored in one byte, except for special formatting characters like ''\n'' and ''\t'', which are still stored in one byte even though they take two symbols to type.

The '' '' things just take one character and translate it to its numerical value, so the following is fine:


mystring[5] = '' ''; // the space character



I''m not sure about the actual numberical values of the characters, so I''ll just assign some random values for example. This is what the mystring looks like in memory:

05 32 49 F8 9A 00 70 02 58 B3 89 C0

A char is one byte, a short is two bytes, an int is four bytes, etc. As long as the type is longer than one byte, we won''t lose and value if we store it in a different type. If we stored the string in an array of shorts, this is what it would look like:

00 05 | 00 32 | 00 49 | 00 F8 | 00 9A | 00 00 | 00 70 | 00 02 | 00 58 | 00 B3 | 00 89 | 00 C0

It''s wasting space, but the values are all there.

MBCS stands for Multi-Byte Character Set. Why would you need to store characters using something larger than a char? Well, they store some kind of translation information or for porting between different platforms with each letter. I think it has something to do with converting to different languages, but I''m not sure.

DBCS stands for Double-Byte Character Set. Unicode is a DBCS because it uses shorts (two bytes) to represent each character. Windows NT uses Unicode exclusively, and Windows 9x uses the normal C-style char strings. Using TSTR and all the relevant typedefs are probably for compatibility with both OS/platforms.

As for why the Win32 API uses so many typedefs and defines, they are used to keep the code portable. If Windows switches over to 64-bit (remember, not so long ago it switched from 16-bit to 32-bit), the code needs to be similar on all platforms. They don''t want to have to go through and change thousands and thousands of instances of int to short (because now int may be 64-bit and short may be 32-bit, and the function really only takes 32-bits, so if it is declared with an int you''re going to have problems...) etc. If they use typedefs, all they have to do is something like this:


#if PLATFORM = 64BIT
#define LPARAM short // still 32 bits!
#define WPARAM short // still 32 bits!

#elif PLATFORM = 32BIT
#define LPARAM long // 32 bits on this platform!
#define WPARAM long // 32 bits on this platform!

#elif PLATFORM = 16BIT
#define LPARAM long // 32 bits?
#define WPARAM long // 32 bits?



My knowledge is failing me, since I never did much programming in 16-bit Windows. There are a lot of issues with porting, but you get the idea - whenever MS needs to change the code definitions to keep it compatible across multiple versions of Windows, it can do so by modifying the typedefs and instead of changing lots of little function declarations all over the place.

If you want to take advantage of that portability, you should use the Windows typedefs just as they are defined when working with the Win32 API.

Well, that''s about all I know on the subject!


- null_pointer
Sabre Multimedia
Ok...I am getting this stuff now a little. A few other questions before everything really fits in.
Now if MBCS, DBCS and Unicode are all 2 bytes why do we need all of them? Do they like have different meanings for each? Another thing, when I do this

PSTR a;
LPTSTR b;
b =(LPTSTR)malloc(10);
a =(PSTR)malloc(10);
strcpy(a, "hello");
strcpy(b, "see");
strcpy(a, b);
strcpy(b, a);
This compiled with no errors or warnings? Now strcpy ask for two char * and LPTSTR is a short * so it should at least give a warning because when it compiles and runs, with a char * it needs to increment by one byte where short * needs to increment by 2 bytes, and strcpy would increment by 1 byte so it should not work? Is this because i''m running it on Windows98, and WindowsNT or Windows2k would act alot different? Should I be using lstrcpy()? Also when I look up strcpy, I see all this
strcpy ANSI, Win 95, Win NT
wcscpy or ANSI, Win 95, Win NT
_mbscpy Win 95, Win NT

now how do I know which ones to use? I also see this wide-character set alot, how is this different than MBCS or DBCS? Windows programming is kinda intimidating in my opinion. I mean how do you know to use PSTR and how do you know when to use
LPTSTR. Most of the Windows API uses LPTSTR, so I guess this is the one you should be using? Thanks if anyone can help me. I know this is alot of questions its just i''m trying to answer alot of questions? Is there a part in the MSDN that I can read that will also help me answer these questions? Thanks once again
Braves



This topic is closed to new replies.

Advertisement