Develop and Download Open Source Software

Browse CVS Repository

Contents of /enbanfukusyaya/EnbanFukusyaYa/Win32/osdepend.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Fri Nov 5 17:24:03 2010 UTC (13 years, 5 months ago) by bananajinn
Branch: MAIN
CVS Tags: HEAD
File MIME type: text/x-csrc
*** empty log message ***

1 /**
2 * @file osdepend.h
3 * @brief OS依存処理
4 * @author BananaJinn
5 * @version $Id: osdepend.c,v 1.2 2010/11/02 15:23:51 bananajinn Exp $
6 * 円盤複写屋
7 * Copyright (C) 2004-2010 BananaJinn<banana@mxh.mesh.ne.jp>
8 */
9 #include <windows.h>
10 #include "osdepend.h"
11 #include "ebstring.h"
12
13 /**
14 * @brief プロセス作成
15 * @param[in] cmdline コマンドライン
16 * @param[out] pid_ret プロセスID
17 * @param[out] stdin_ret 標準入力ディスクリプタ
18 * @param[out] stdout_ret 標準出力ディスクリプタ
19 * @param[out] stderr_ret 標準エラー出力ディスクリプタ
20 * @return 成功時は TRUE を返す。
21 */
22 BOOL OSDCreateProcess(const char *cmdline, OSD_PID *pid_ret,
23 OSD_FD *stdin_ret, OSD_FD *stdout_ret,
24 OSD_FD *stderr_ret)
25 {
26 HANDLE tmp;
27 HANDLE stdin_r, stdin_w;
28 HANDLE stdout_r, stdout_w;
29 HANDLE stderr_r, stderr_w;
30 SECURITY_ATTRIBUTES sa;
31 PROCESS_INFORMATION pi;
32 STARTUPINFO si;
33 BOOL bRet;
34 char *cmdline_copy = NULL;
35
36 ZeroMemory(&sa, sizeof(sa));
37 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
38 sa.bInheritHandle = TRUE;
39
40 if(stdin_ret != NULL){
41 if(CreatePipe(&stdin_r, &tmp, &sa, 0) == FALSE){
42 return FALSE;
43 }
44 bRet = DuplicateHandle(GetCurrentProcess(), tmp,
45 GetCurrentProcess(), &stdin_w,
46 0, FALSE, DUPLICATE_SAME_ACCESS);
47 CloseHandle(tmp);
48 if(bRet == FALSE){
49 CloseHandle(stdin_r);
50 return FALSE;
51 }
52 }
53 if(stdout_ret != NULL){
54 if(CreatePipe(&tmp, &stdout_w, &sa, 0) == FALSE){
55 if(stdin_ret != NULL){
56 CloseHandle(stdin_r);
57 CloseHandle(stdin_w);
58 }
59 return FALSE;
60 }
61 bRet = DuplicateHandle(GetCurrentProcess(), tmp,
62 GetCurrentProcess(), &stdout_r,
63 0, TRUE, DUPLICATE_SAME_ACCESS);
64 CloseHandle(tmp);
65 if(bRet == FALSE){
66 CloseHandle(stdout_w);
67 if(stdin_ret != NULL){
68 CloseHandle(stdin_r);
69 CloseHandle(stdin_w);
70 }
71 return FALSE;
72 }
73 }
74 if(stderr_ret != NULL){
75 if(CreatePipe(&tmp, &stderr_w, &sa, 0) == FALSE){
76 if(stdin_ret != NULL){
77 CloseHandle(stdin_r);
78 CloseHandle(stdin_w);
79 }
80 if(stdout_ret != NULL){
81 CloseHandle(stdout_r);
82 CloseHandle(stdout_w);
83 }
84 return FALSE;
85 }
86 bRet = DuplicateHandle(GetCurrentProcess(), tmp,
87 GetCurrentProcess(), &stderr_r,
88 0, TRUE, DUPLICATE_SAME_ACCESS);
89 CloseHandle(tmp);
90 if(bRet == FALSE){
91 CloseHandle(stderr_w);
92 if(stdin_ret != NULL){
93 CloseHandle(stdin_r);
94 CloseHandle(stdin_w);
95 }
96 if(stdout_ret != NULL){
97 CloseHandle(stdout_r);
98 CloseHandle(stdout_w);
99 }
100 return FALSE;
101 }
102 }
103
104 ZeroMemory(&si, sizeof(si));
105 si.cb = sizeof(STARTUPINFO);
106 si.dwFlags = STARTF_USESTDHANDLES;
107 si.hStdInput = stdin_ret != NULL ?
108 stdin_r : GetStdHandle(STD_INPUT_HANDLE);
109 si.hStdOutput = stdout_ret != NULL ?
110 stdout_w : GetStdHandle(STD_OUTPUT_HANDLE);
111 si.hStdError = stderr_ret != NULL ?
112 stderr_w : GetStdHandle(STD_ERROR_HANDLE);
113
114 cmdline_copy = EbStringNew(cmdline);
115 bRet = CreateProcess(NULL, cmdline_copy, NULL, NULL, TRUE,
116 NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,
117 NULL, NULL, &si, &pi);
118 cmdline_copy = EbStringFree(cmdline_copy);
119 if(bRet == FALSE){
120 if(stdin_ret != NULL){
121 CloseHandle(stdin_r);
122 CloseHandle(stdin_w);
123 }
124 if(stdout_ret != NULL){
125 CloseHandle(stdout_r);
126 CloseHandle(stdout_w);
127 }
128 if(stderr_ret != NULL){
129 CloseHandle(stderr_r);
130 CloseHandle(stderr_w);
131 }
132 return FALSE;
133 }
134 if(stdin_ret != NULL){
135 *stdin_ret = stdin_w;
136 CloseHandle(stdin_r);
137 }
138 if(stdout_ret != NULL){
139 *stdout_ret = stdout_r;
140 CloseHandle(stdout_w);
141 }
142 if(stderr_ret != NULL){
143 *stderr_ret = stderr_r;
144 CloseHandle(stderr_w);
145 }
146 *pid_ret = pi.hProcess;
147 CloseHandle(pi.hThread);
148 Sleep(100);
149 return TRUE;
150 }
151
152 /**
153 * @brief プロセスを強制終了する
154 * @param[in] pid プロセスID
155 * return 成功時は TRUE を返す。
156 */
157 BOOL OSDTerminateProcess(OSD_PID pid)
158 {
159 return TerminateProcess(pid, 0);
160 }
161
162 /**
163 * @brief プロセスの終了を待つ
164 * @param[in] pid プロセスID
165 * @param[out] exitcode_ret 終了コード
166 * @return 成功時は TRUE を返す。
167 */
168 BOOL OSDWaitProcess(OSD_PID pid, int *exitcode_ret)
169 {
170 DWORD exitcode = 0;
171
172 WaitForSingleObject(pid, INFINITE);
173 GetExitCodeProcess(pid, &exitcode);
174 CloseHandle(pid);
175 if(exitcode_ret != NULL){
176 *exitcode_ret = (int)exitcode;
177 }
178
179 return TRUE;
180 }
181
182 /**
183 * @brief ディスクリプタから指定サイズの読み込みを行う。
184 * @param[in] fd_stdout 標準出力ディスクリプタ
185 * @param[in] fd_stderr 標準エラー出力ディスクリプタ
186 * @param[out] buff_stdout 標準出力バッファ
187 * @param[in] size_stdout 標準出力バッファサイズ
188 * @param[out] stderr_ret 標準エラー出力返却用文字列ポインタのアドレス
189 * @return 読み込んだサイズ(バイト数)を返す。
190 */
191 int OSDRead(OSD_FD fd_stdout, OSD_FD fd_stderr,
192 unsigned char *buff_stdout, int size_stdout,
193 char **stderr_ret)
194 {
195 #define ISINVALID(v) ((v)==INVALID_HANDLE_VALUE)
196 int ret;
197 int offset_stdout = 0;
198 char buff_stderr[256+1];
199 BOOL done = FALSE;
200 BOOL bRet;
201 DWORD dwReadBytes;
202 DWORD dwAvailBytes;
203
204 if(!ISINVALID(fd_stderr)){
205 if(stderr_ret != NULL){
206 *stderr_ret = NULL;
207 }
208 }
209
210 while(!done && (!ISINVALID(fd_stdout) || !ISINVALID(fd_stderr))){
211 if(!ISINVALID(fd_stdout)){
212 dwReadBytes = 0;
213 bRet = ReadFile(fd_stdout, buff_stdout+offset_stdout,
214 size_stdout-offset_stdout,
215 &dwReadBytes, NULL);
216 if(bRet == FALSE){
217 fd_stdout = INVALID_HANDLE_VALUE;
218 }
219 else{
220 offset_stdout += dwReadBytes;
221 if(offset_stdout >= size_stdout){
222 done = TRUE;
223 }
224 }
225 }
226 if(!ISINVALID(fd_stderr)){
227 while(TRUE){
228 bRet = PeekNamedPipe(fd_stderr, NULL, 0,
229 NULL, &dwAvailBytes, NULL);
230 if(bRet == FALSE){
231 fd_stderr = INVALID_HANDLE_VALUE;
232 break;
233 }
234 if(dwAvailBytes == 0){
235 break;
236 }
237 if(dwAvailBytes > sizeof(buff_stderr)-1){
238 dwAvailBytes = sizeof(buff_stderr)-1;
239 }
240 bRet = ReadFile(fd_stderr, buff_stderr,
241 dwAvailBytes, &dwReadBytes, NULL);
242 if(bRet == FALSE){
243 fd_stderr = INVALID_HANDLE_VALUE;
244 break;
245 }
246 buff_stderr[dwReadBytes] = '\0';
247 *stderr_ret = EbStringAppend(*stderr_ret, buff_stderr);
248 }
249 }
250 }
251 return offset_stdout;
252 }
253
254 /**
255 * @brief ディスクリプタを閉じる。
256 * @param[in] fd ディスクリプタ
257 */
258 void OSDFDClose(OSD_FD fd)
259 {
260 CloseHandle(fd);
261 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26