I'm trying to test an application on a write protected USB drive, I want to use the ShellExecuteEx API (I need to use this API call because I need the lpVerb := "runas") call to execute a second program, but I keep getting a "Write Protect Error" with the ShellExecuteEx call. I can’t seem to figure out what’s trying to write to the drive, I have no code that is writing to the drive and I even used the latest Microsoft Standard User Analyzer and Application Verifier to try and verify what is trying to write to the drive with no success. Here is the error I keep getting:
[ Write Protect Error ]
Nothing in the following code is trying to write to this drive, is the ShellExecuteEx API call the wrong way to do what I'm trying to do? If not, how can I get this error from popping up. Any help would be greatly appreciated.
[ WP-ON.reg ]
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies]
"WriteProtect"=dword:00000001
[ WP-OFF.reg ]
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies]
"WriteProtect"=dword:00000000
NOTE: You must eject and reinsert the device each time the registry has been updated.
[ project1.dpr ]
program project1;
{.$APPTYPE CONSOLE}
uses
Windows, SysUtils;
begin
Windows.MessageBox(Windows.GetActiveWindow(),
PChar('Hello World!'), PChar('project1'), MB_OK);
end.
[ launch.manifest ]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity processorArchitecture="x86" version="2.0.1.0" name="eyeClaxton.asInvoker.Launch" type="win32" />
<description>asInvoker Launch</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="x86" />
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
[ launch.dpr ]
program launch;
uses
Windows, ShellAPI;
{$R 'MANIFEST.RES'}
procedure ShellEx(const theFilename, theParams: string);
function RunAsAdmin(): Boolean;
var
OSVerInfo: TOSVersionInfo;
begin
OSVerInfo.dwOSVersionInfoSize := System.SizeOf(OSVerInfo);
Result := (Windows.GetVersionEx(OSVerInfo)) and (OSVerInfo.dwMajorVersion > 5);
end;
var
ShellExInfo: TShellExecuteInfo;
Directory: array[0..MAX_PATH] of Char;
begin
Windows.ZeroMemory(@ShellExInfo, System.SizeOf(ShellExInfo));
ShellExInfo.cbSize := System.SizeOf(TShellExecuteInfo);
ShellExInfo.Wnd := Windows.GetActiveWindow();
ShellExInfo.nShow := SW_SHOWNORMAL;
ShellExInfo.fMask := SEE_MASK_FLAG_NO_UI;
if (RunAsAdmin()) then // If OS is greater than Windows XP
ShellExInfo.lpVerb := PChar('runas');
Windows.ZeroMemory(@Directory, System.SizeOf(Directory));
Windows.GetCurrentDirectory(SizeOf(Directory), Directory);
ShellExInfo.lpDirectory := PChar(string(Directory));
ShellExInfo.lpFile := PChar('"' + string(Directory) + '\' + theFilename + '"');
ShellExInfo.lpParameters := PChar('"' + theParams + '"');
//
// ShellExecuteEx causes a "Write Protect" error to popup.
//
if (not ShellAPI.ShellExecuteEx(@ShellExInfo)) then
Windows.MessageBox(Windows.GetActiveWindow(),
PChar('File ' + ShellExInfo.lpFile + ' not found!'),
PChar('asInvoker Launch'), MB_OK or MB_ICONERROR);
end;
begin
ShellEx('project1.exe', System.ParamStr(1));
end.