summaryrefslogtreecommitdiff
path: root/GnuPG/pipeexec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'GnuPG/pipeexec.cpp')
-rw-r--r--GnuPG/pipeexec.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/GnuPG/pipeexec.cpp b/GnuPG/pipeexec.cpp
new file mode 100644
index 0000000..facb7aa
--- /dev/null
+++ b/GnuPG/pipeexec.cpp
@@ -0,0 +1,133 @@
+#include "gnupgplugin.h"
+
+BOOL isWindowsNT(void)
+{
+ OSVERSIONINFO ovi;
+
+ ZeroMemory(&ovi,sizeof(ovi));
+ ovi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
+ GetVersionEx(&ovi);
+
+ return (ovi.dwPlatformId==VER_PLATFORM_WIN32_NT)?TRUE:FALSE;
+}
+
+void storeOutput(HANDLE ahandle, char **aoutput)
+{
+ BOOL success;
+ char readbuffer[10];
+ unsigned long transfered, available;
+
+ do {
+ PeekNamedPipe(ahandle,NULL,0,NULL,&available,NULL);
+ if (!available)
+ continue;
+ success=ReadFile(ahandle,readbuffer,sizeof(readbuffer),&transfered,NULL);
+ if (success && transfered)
+ appendText(aoutput,readbuffer,transfered);
+ } while (available>0);
+}
+
+pxResult pxExecute(char *acommandline, char *ainput, char **aoutput, LPDWORD aexitcode)
+{
+ BOOL success;
+ STARTUPINFO startupinfo;
+ SECURITY_ATTRIBUTES securityattributes;
+ SECURITY_DESCRIPTOR securitydescriptor;
+ PROCESS_INFORMATION processinformation;
+ HANDLE newstdin, newstdout, readstdout, writestdin;
+ char *inputpos;
+ unsigned long transfered;
+ int size;
+
+ LogMessage("--- GnuPG.pxExecute: commandline:\n",acommandline,"\n");
+
+ ZeroMemory(&securityattributes,sizeof(securityattributes));
+ securityattributes.nLength=sizeof(SECURITY_ATTRIBUTES);
+ securityattributes.bInheritHandle=TRUE;
+
+ if (isWindowsNT())
+ {
+ InitializeSecurityDescriptor(&securitydescriptor,SECURITY_DESCRIPTOR_REVISION);
+ SetSecurityDescriptorDacl(&securitydescriptor,TRUE,NULL,FALSE);
+ securityattributes.lpSecurityDescriptor=&securitydescriptor;
+ }
+ else securityattributes.lpSecurityDescriptor=NULL;
+
+ success=CreatePipe(&newstdin,&writestdin,&securityattributes,0);
+ if (!success)
+ {
+ LogMessage("--- GnuPG.pxExecute: ","stdin create pipe failed","\n");
+ return pxCreatePipeFailed;
+ }
+
+ success=CreatePipe(&readstdout,&newstdout,&securityattributes,0);
+ if (!success)
+ {
+ LogMessage("--- GnuPG.pxExecute: ","stdout create pipe failed","\n");
+ CloseHandle(newstdin);
+ CloseHandle(writestdin);
+ return pxCreatePipeFailed;
+ }
+
+ GetStartupInfo(&startupinfo);
+ startupinfo.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
+ startupinfo.wShowWindow=SW_HIDE;
+ startupinfo.hStdOutput=newstdout;
+ startupinfo.hStdError=newstdout;
+ startupinfo.hStdInput=newstdin;
+
+ success=CreateProcess
+ (
+ NULL,
+ (LPTSTR)acommandline,
+ NULL,
+ NULL,
+ TRUE,
+ CREATE_NEW_CONSOLE,
+ NULL,
+ NULL,
+ &startupinfo,
+ &processinformation
+ );
+
+ if (!success)
+ {
+ LogMessage("--- GnuPG.pxExecute: ", "create process failed", "\n");
+ CloseHandle(newstdin);
+ CloseHandle(writestdin);
+ CloseHandle(newstdout);
+ CloseHandle(readstdout);
+ return pxCreateProcessFailed;
+ }
+
+ inputpos=ainput;
+
+ while (TRUE)
+ {
+ success=GetExitCodeProcess(processinformation.hProcess,aexitcode);
+ if (success && *aexitcode!=STILL_ACTIVE)
+ break;
+
+ storeOutput(readstdout,aoutput);
+
+ if (*inputpos!='\0') size=1;
+ else size=0;
+
+ success=WriteFile(writestdin,inputpos,size,&transfered,NULL);
+ inputpos+=transfered;
+ }
+
+ storeOutput(readstdout,aoutput);
+ WaitForSingleObject(processinformation.hProcess,INFINITE);
+
+ LogMessage("--- GnuPG.pxExecute: output:\n",*aoutput,"");
+
+ CloseHandle(processinformation.hThread);
+ CloseHandle(processinformation.hProcess);
+ CloseHandle(newstdin);
+ CloseHandle(newstdout);
+ CloseHandle(readstdout);
+ CloseHandle(writestdin);
+
+ return pxSuccess;
+}