ShellExecuteEx Error on Write Protected Hard Disk?

I'm trying to test the 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 the second program, but I keep getting "Write Protect Error "with a call to ShellExecuteEx. I can’t understand what I’m trying to write to disk, I don’t have the code that writes to disk, and I even used the latest Microsoft User User Analyzer and Application Verifier to try and verify what I was trying to write to disk without success. Here is the error that I keep getting:

[Write protect error]

Write Protect Error

Nothing in the following code is trying to write to this disk, is the ShellExecuteEx API 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 unload and reinsert the device each time the registry is 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. 
+4
source share
1 answer

The problem arises because ShellExecuteEx is a rather complicated process, starting a new background thread and then calling a lot of COM stuff. The recording must be activated somewhere for security reasons.

You can try disabling UAC. But this is not a good solution.

When you look at the appropriate solutions to programmatically elevate the process (a wired manifest is another static way to elevate), you can only find the two indicated in this SO answer :

  • Use ShellExecuteEx with runas parameter;
  • Create an elevated COM object using the makeup prefix "Elevation: Administrator! New:".

It is worth reading the entire article "Vista UAC: The Definitive Guide" to understand how ShellExecuteEx works.

So here is my answer: since you need to run the process with elevated rights, and there is no existing API "CreateProcessElevated", but only a good big ShellExecute, it is easiest to use the manifest file for the second executable.

If you want your project1.exe file to work with "AsInvoker" rights, but only with administrator rights, you have two options:

  • Use an external .manifest file and do not embed the file in exe as a resource, and then replace the contents of .manifest with one version with either the "AsInvoker" parameter or the "requireAdministrator", but difficult to read - only media, isn't it :;
  • Use an external 3rd executable (we will call it Elevate.exe ) containing a manifest with the level of "requireAdministrator" that will launch the second executable. You could provide exe and command line as a parameter to this program Elevate.exe .
+6
source

All Articles