If you look at the MSDN documentation of CreateProcess you might notice the following remark for the lpCommandLine parameter:
The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
This means that when you move over to Unicode (Delphi 2009/2010) existing code might produce an Access Violation.
This code for example will produce an Access Violation:
To prevent these kinds of Access Violation we could change the declaration of the lpCommandLine parameter as var. This prevents passing nil though (which is allowed).
So if we want to allow passing nil but not a constant we should declare 2 overloaded functions:
and
I choose PByte in the second declaration because it allows for nil but disallows PChar(‘notepad.exe’) which will also AV.
So what do you think? Should we change this in Jwa?
7 Responses
Patrick van Logchem
12|Nov|2009 1Nice idea – but there are many more functions that are originally declared as having pointer argument(s), but are instead declared as having ‘var’ arguments in Jwa, which indeed prevents passing nil pointers (like GetModuleHandleEx).
Why exactly did you choose for ‘var’ arguments in the first place? Because the Delphi RTL does the same? And why is that exactly?
And how are we supposed to call those methods when all we have is a pointer? Passing ({var}aPointer^) seems rather messy… especially when the pointer could be a nil value!
And in this situation, how should we retrieve the address of one specific overloaded function?
Also, are you planning to overload all API’s that have the same possible problem? (That is, given we can determine which ones they are.)
Remko
12|Nov|2009 2Well it’s just a thought to improve this part where existing code might produce an access violation. I didn’t have the idea to change many functions like this… That said: if you have concrete examples of functions where it is a problem we can always correct those specific ones.
Indeed the idea is to translate pointer type to var *unless* nil may be passed. I don’t know if this was originally done because it’s convenient or make the translations close to the delphi ones.
I didn’t think about dynamically loaded functions at all, so this is a useful comment. I am open for suggestions
Stebi
12|Nov|2009 3Is this safe?
var
CmdLine: string;
[...]
CreateProcess(”, PChar(CmdLine), …);
Remko
12|Nov|2009 4Yes as long as the string has a reference count it’s safe. This would not be safe though:
const
cCmdLine: string = ‘notepad.exe’;
var
sCmdLine: string;
begin
sCmdLine := cCmdLine;
CreateProcess(nil, PChar(sCmdLine)
Krystian
12|Nov|2009 5Simple way to make it safe is to use UniqueString:
const
cCmdLine: string = ‘notepad.exe’;
var
sCmdLine: string;
begin
sCmdLine := cCmdLine;
UniqueString(sCmdLine); // This line can be surrounded by {$IFDEF UNICODE}…{$ENDIF}, but not required
CreateProcess(nil, PChar(sCmdLine), …
Javier Santo Domingo
12|Nov|2009 6I vote for the “var” modificator, a pointer can be nil.
Christian Wimmer
12|Nov|2009 7@Krystian
Yes, you can make things safe in this way but it also means you need to know how. By using the compiler programmers won’t make this error from the beginning because the compiler shows an error.
Leave a reply
Search
Paypal donation (EUR)
Download Win 7 Search Provider
Categories
Archives
Tags
Recent Posts
Recent Comments
Blogroll
JEDI Sites
Pages
A design creation of Design Disease
Copyright © 2007 - JEDI Windows API - is proudly powered by WordPress
InSense 1.0 Theme by Design Disease brought to you by HostGator Web Hosting.