Hi all. On my ever winding quest to fill in the win32 API documentation, I have found, I think, an intresting issue. When the documentation is generated with c2man.pl, it checks the .spec file to see if the function is a stub or not. The problem is that if it is a stub, no documentation will be generated for that API. I've decieded to take it upon myself to "fill in the blankes" as it were, but I need to know if I'm doing this correctly.
For my example I'm going to use the stubbed function "AdjustTokenGroups" that is found in avdapi32.dll.
The fist thing I did was update the .spec file so c2man.pl will parse the function correctly.
I changed @ stub AdjustTokenGroups
to: @ stdcall AdjustTokenGroups (long long ptr long ptr ptr)
That allows c2man to parse the function. So now all I need to do is add that function to security.c. I added the following. --------------------- /****************************************************** * AdjustTokenGroups [ADVAPI32.@] * * Adjust the group privileges of an open token handle. * */
BOOL WINAPI AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState, DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
{ } -------------------------
And whamo-blamo, the documentation is generated...
Now, I'm not too hot on coding, did I just break something to get my API to document? Should I be adding a fixme? Should I be returning something even though it's an empty function? I didn't compile it to see if it worked.The AdjustTokenGroups.html file that was generated says "Not defined in a Wine header. The function is either undocumented, or missing from Wine." Is it ok to leave that right now? Should I me putting something in a header file somewhere?
Just wondering.
-Joshua
On Sunday 28 December 2003 10:16 pm, Joshua Walker wrote:
Hi all. On my ever winding quest to fill in the win32 API documentation, I have found, I think, an intresting issue. When the documentation is generated with c2man.pl, it checks the .spec file to see if the function is a stub or not. The problem is that if it is a stub, no documentation will be generated for that API. I've decieded to take it upon myself to "fill in the blankes" as it were, but I need to know if I'm doing this correctly.
For my example I'm going to use the stubbed function "AdjustTokenGroups" that is found in avdapi32.dll.
The fist thing I did was update the .spec file so c2man.pl will parse the function correctly.
I changed @ stub AdjustTokenGroups
to: @ stdcall AdjustTokenGroups (long long ptr long ptr ptr)
looks right (assuming you have the right calling convention).
That allows c2man to parse the function. So now all I need to do is add that function to security.c. I added the following.
/******************************************************
- AdjustTokenGroups [ADVAPI32.@]
- Adjust the group privileges of an open token
handle.
*/
BOOL WINAPI AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState, DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
{ }
And whamo-blamo, the documentation is generated...
hmm...
Now, I'm not too hot on coding, did I just break something to get my API to document?
Yes, I'm afraid so. These are excellent questions, so I've annotated each one.
Should I be adding a fixme?
Yep. The pattern to follow would be to put a "stub" fixme, you will see examples in the source... but see below for more caveats :)
Should I be returning something even though it's an empty function?
Yes, "proper" C coding requires that any function with a return type other than "void" return something. When you compile, you will see a new compiler warning about this. Now, /what/ to return, may take some thinking, or, depending on the function, even some code to construct dummy structures, etc, even though there is no real functionality in your stub.
I didn't compile it to see if it worked.
You probably would want to do so, if you take this approach. The best (well, the quickest) way I know of is to compile a test with a Microsoft compiler, run it in Windows to make sure it works, and then run it in wine. If you see your fixme, and there is no crash, then you probably have it right.
The AdjustTokenGroups.html file that was generated says "Not defined in a Wine header. The function is either undocumented, or missing from Wine." Is it ok to leave that right now? Should I me putting something in a header file somewhere?
Often, you need to ("ought to" might be more accurate) define a function in a wine header somewhere. The trick is to get the Platform SDK from Microsoft and grep for the function definition in their headers. Now you know which header it belongs in :) So open that header in your editor, and follow the existing coding conventions you see there (i.o.w., do not cut-and-paste from the Microsoft header). However, the definition might already be in the wine headers (even though the function wasn't in wine), so grep there first.
Now, here comes the bad news: many Windows programs do the following:
o Reach the point where it would be appropriate to call XYZFunction o Call GetProcAddress for XYZFunction o branch: if it comes back as NULL, assume it does not exist in this version of windows. Go down codepath A. Otherwise, codepath B.
This means, sometimes, you could change the behavior of a program, by implementing the stub. This has been a problem in wine before. It seems tempting to just create stubs for everything, but this can break working apps (or fix broken ones -- it's a balancing act).
With a function like AdjustTokenGroups, which I presume is NT-specific, I'm afraid Alexandre is probably going to reject the patch unless the function has some kind of meaningful implementation, or a stated reason to be there.
So, you have a couple choices:
1) Convince somebody to change the documentation thingy to work even though there's a stub (or make this change yourself) 2) Stick to documenting functions wine already has.
Your call, but I suggest route #2: There are many, many, many functions already implemented in wine, but undocumented. Enough to keep you busy for years, I would bet. Furthermore, the functions implemented in wine are the ones that are going to be used most frequently in Windows apps (for obvious reasons).
Glad to see you are still at this -- good luck!
Thanks for the reply...
--- "Gregory M. Turner" gmturner007@ameritech.net wrote:
[A Bunch of really insightful stuff]
Implementing should best be left to the implemnters. ^_^
I'll leave the stub in the .spec file, leaving the unimplemnted functions undocumented. This has some advantages. First c2man,pl was thinking that the function was actually implemnted and incorrectly updating the stats. Second, when you have an HTML page full of links to various API definitions, the stubs start to really jump out at you.
But some issues do arise. One of them is a rather intresting thing I found out about advapi32.dll. There are 33 undocumented system fuctions, SystemFunction001 through SystemFunction033. It has come to my attention via an NT Crypto god that these are actually encrypters/decrypters for various ciphers. RC4, MD4, DES, ECB mode DES, and the like. It would be kinda keen to put a "stcky note" somewhere as to not lose gems of information like that. You can put in roumors and other tales of undocumented intreague.
Then gain, I guess I could always push comments like that out to the DLL document itself, or just snuggle them in the code where they won't get parsed by c2man.
Doing the documentaion isn't that bad. A lot of the handles, pointers, discriptors, and wotnot are used over and over and over again. The hard bit is not using MSDN, but that's tricky as all the other API websites I've found blatently rip off MSDN anyway. This coupled with the facts that the auto-genertaed API docs are fightenly close to MSDN's API format, and that you can only really document and API so many ways, You find yourself in a box a little smaller than confortable. I refer to MSDN as a refrence, but only to make sure that I didn't make a copy of what they said with my own words on accident.
Anyway I'm up waaaay too late now. I'm going to submit patches on a dll-by-dll basis.
You have not heard the last of me........
-Joshua