2011-07-08 48 views
4

我試圖在寫保護的USB驅動器上測試應用程序,我想使用ShellExecuteEx API(我需要使用此API調用,因爲我需要lpVerb:=「runas」)調用來執行第二個程序,但我一直在用ShellExecuteEx調用獲得「寫保護錯誤」。我似乎無法弄清楚發生了什麼嘗試寫入的驅動器,我沒有代碼被寫入驅動器,我甚至使用了最新的Microsoft Standard User AnalyzerApplication Verifier嘗試和驗證什麼是試圖寫入到驅動器沒有成功。這裏是我不斷收到錯誤:寫保護的USB驅動器上的ShellExecuteEx錯誤?

[寫保護錯誤]

Write Protect Error

在下面的代碼沒有試圖寫這個驅動器,是的ShellExecuteEx API調用錯誤的方式做我想做的事情?如果沒有,我怎麼能從彈出的這個錯誤。任何幫助將不勝感激。

[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 

注:您必須退出,每次重新插入設備註冊表已更新。

[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. 
+0

嘗試使用'Process Monitor' http://technet.microsoft.com/en-us/sysinternals/bb896645,通過此工具,您可以檢查任何進程的文件系統活動。 – RRUZ

+2

我懷疑ShellExecuteEx正在嘗試寫入驅動器。第二個程序如何訪問該文件?你確定第二個程序甚至啓動? –

+0

@提供第二個程序源代碼(project1.dpr)。它什麼都不做,只是顯示一個消息框。問題是第二個程序甚至沒有啓動,因爲ShellExecute返回一個錯誤。 –

回答

6

問題來˚F從事實ShellExecuteEx是一個相當複雜的過程,開始一個新的後臺線程,然後調用很多COM的東西。出於安全原因,應該在某處啓用寫入。

您可以嘗試禁用UAC。但不是一個好的解決方案。

當你在相應的解決方案,以提升編程過程的權利(有線清單是擡高的另一靜態的方式),你只能找到兩個quoted in this SO answer

  • 使用的ShellExecuteEx與runas參數;
  • 創建一個具有魔力升高COM對象「海拔:管理員新:」前綴。

這是值得一讀的整個"Vista UAC: The Definitive Guide"文章,瞭解如何的ShellExecuteEx作品。

因此,這裏是我的回答:因爲你需要運行以提升權限的過程中,並沒有存在的「CreateProcessElevated」 API,但只有好大ShellExecute的,最容易就是使用了一個清單文件第二可執

如果你希望你的PROJECT1.EXE文件與「AsInvoker」權限運行,但只有在目的管理員權限,你有兩種可能性:

  • 使用外部文件,不嵌入文件作爲資源的exe文件 - 然後用「AsInvoker」或「requireAdministrator」參數替換一個版本的內容 - 但在只讀介質上很難,是不是:
  • 使用外部第3個可執行文件(我們將其稱爲Elevate.exe),其中包含具有「requireAdministrator」級別的清單,該清單將啓動第2個可執行文件。你可以提供exe和命令行作爲這個Elevate.exe程序的參數。
+0

我不需要project1.exe在Windows XP上運行提升,我會測試操作系統版本,然後調用WinExec API(如果檢測到XP)。經過測試和工作!非常感謝您的幫助。 – eyeClaxton