00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "htsys.h"
00023 #include "qword.h"
00024 #include "snprintf.h"
00025
00026 #include <ctype.h>
00027 #include <errno.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031 #include <sys/stat.h>
00032
00033 #ifndef WIN32_LEAN_AND_MEAN
00034 #define WIN32_LEAN_AND_MEAN
00035 #endif
00036 #include <windows.h>
00037
00038 struct winfindstate {
00039 HANDLE fhandle;
00040 WIN32_FIND_DATA find_data;
00041 };
00042
00043 int sys_canonicalize(char *result, const char *filename)
00044 {
00045 char *dunno;
00046 return (GetFullPathName(filename, HT_NAME_MAX, result, &dunno) > 0) ? 0 : ENOENT;
00047 }
00048
00049 dword filetime_to_ctime(FILETIME f)
00050 {
00051 qword q;
00052 QWORD_SET_LO(q, f.dwLowDateTime);
00053 QWORD_SET_HI(q, f.dwHighDateTime);
00054 q = q / int_to_qword(10000000);
00055 return QWORD_GET_LO(q) + 1240431886;
00056 }
00057
00058 void sys_findfill(pfind_t *pfind)
00059 {
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 winfindstate *wfs=(winfindstate*)pfind->findstate;
00071 pfind->name = (char *)&wfs->find_data.cFileName;
00072 pfind->stat.caps = pstat_ctime|pstat_mtime|pstat_atime|pstat_size|pstat_mode_type;
00073 pfind->stat.size = wfs->find_data.nFileSizeLow;
00074 pfind->stat.size_high = wfs->find_data.nFileSizeHigh;
00075 pfind->stat.mode = (wfs->find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? HT_S_IFDIR : HT_S_IFREG;
00076 pfind->stat.ctime = filetime_to_ctime(wfs->find_data.ftCreationTime);
00077 pfind->stat.mtime = filetime_to_ctime(wfs->find_data.ftLastWriteTime);
00078 pfind->stat.atime = filetime_to_ctime(wfs->find_data.ftLastAccessTime);
00079 }
00080
00081 int sys_findfirst(const char *dirname, pfind_t *pfind)
00082 {
00083 char *Dirname = (char *)malloc(strlen(dirname)+5);
00084 strcpy(Dirname, dirname);
00085 int dnl=strlen(dirname);
00086 if ((dirname[dnl-1]!='\\') && (dirname[dnl-1]!='/')) {
00087 Dirname[dnl]='\\';
00088 Dirname[dnl+1]=0;
00089 }
00090 char *s=Dirname;
00091 while ((s=strchr(s, '/'))) *s='\\';
00092 strcat(Dirname, "*.*");
00093
00094 pfind->findstate=malloc(sizeof (winfindstate));
00095 winfindstate *wfs=(winfindstate*)pfind->findstate;
00096
00097 wfs->fhandle = FindFirstFile(Dirname, &wfs->find_data);
00098 free(Dirname);
00099 if (wfs->fhandle == INVALID_HANDLE_VALUE) {
00100 free(pfind->findstate);
00101 return ENOENT;
00102 }
00103 sys_findfill(pfind);
00104 return 0;
00105 }
00106
00107 int sys_findnext(pfind_t *pfind)
00108 {
00109 winfindstate *wfs=(winfindstate*)pfind->findstate;
00110
00111 if (!FindNextFile(wfs->fhandle, &wfs->find_data)) {
00112 return ENOENT;
00113 }
00114 sys_findfill(pfind);
00115 return 0;
00116 }
00117
00118 int sys_findclose(pfind_t *pfind)
00119 {
00120 int r=FindClose(((winfindstate*)pfind->findstate)->fhandle);
00121 free(pfind->findstate);
00122 return r ? ENOENT : 0;
00123 }
00124
00125 int sys_pstat(pstat_t *s, const char *filename)
00126 {
00127 char fn[HT_NAME_MAX];
00128 strncpy(fn, filename, sizeof fn);
00129 int flen = strlen(fn);
00130 if (flen && sys_is_path_delim(fn[flen-1]) && (flen !=3) || (fn[1]!=':')) fn[flen-1] = 0;
00131 struct stat st;
00132 int e = stat(fn, &st);
00133 if (e) return ENOENT;
00134 s->caps = pstat_ctime|pstat_mtime|pstat_atime|pstat_uid|pstat_gid|pstat_mode_all|pstat_size|pstat_inode;
00135 s->ctime = st.st_ctime;
00136 s->mtime = st.st_mtime;
00137 s->atime = st.st_atime;
00138 s->gid = st.st_uid;
00139 s->uid = st.st_gid;
00140 s->mode = sys_ht_mode(st.st_mode);
00141 s->size = st.st_size;
00142 s->size_high = 0;
00143 s->fsid = st.st_ino;
00144 return 0;
00145 }
00146
00147 void sys_suspend()
00148 {
00149 Sleep(42);
00150 }
00151
00152 int sys_get_free_mem()
00153 {
00154 return 0;
00155 }
00156
00157 int sys_truncate(const char *filename, FILEOFS ofs)
00158 {
00159 HANDLE hfile = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
00160 if (hfile == INVALID_HANDLE_VALUE) {
00161 return EIO;
00162 }
00163 if (SetFilePointer(hfile, ofs, NULL, FILE_BEGIN)==0xffffffff) {
00164 CloseHandle(hfile);
00165 return EIO;
00166 }
00167 if (!SetEndOfFile(hfile)) {
00168 CloseHandle(hfile);
00169 return EIO;
00170 }
00171 CloseHandle(hfile);
00172 return 0;
00173 }
00174
00175 int sys_deletefile(const char *filename)
00176 {
00177 if (DeleteFile(filename)) {
00178 return 0;
00179 }
00180 return EIO;
00181 }
00182
00183 bool sys_is_path_delim(char c)
00184 {
00185 return (c == '\\');
00186 }
00187
00188 int sys_filename_cmp(const char *a, const char *b)
00189 {
00190 while (*a && *b) {
00191 if (sys_is_path_delim(*a) && sys_is_path_delim(*b)) {
00192 } else if (tolower(*a) != tolower(*b)) {
00193 break;
00194 } else if (*a != *b) {
00195 break;
00196 }
00197 a++;
00198 b++;
00199 }
00200 return tolower(*a) - tolower(*b);
00201 }
00202
00203
00204
00205
00206
00207 class ht_win32_file: public ht_streamfile {
00208 private:
00209 HANDLE h;
00210 public:
00211 void init(HANDLE h);
00212
00213 virtual UINT read(void *buf, UINT size);
00214 virtual UINT write(const void *buf, UINT size);
00215 };
00216
00217 void ht_win32_file::init(HANDLE H)
00218 {
00219 ht_streamfile::init();
00220 h = H;
00221 }
00222
00223 UINT ht_win32_file::read(void *buf, UINT size)
00224 {
00225 DWORD avail, unread;
00226 if (!PeekNamedPipe(h, NULL, 0, NULL, &avail, &unread)) return 0;
00227 DWORD n = 0;
00228 if (avail) {
00229 int c = (avail > size) ? size : avail;
00230 if (!ReadFile(h, buf, c, &n, NULL)) n = 0;
00231 }
00232 return n;
00233 }
00234
00235 UINT ht_win32_file::write(const void *buf, UINT size)
00236 {
00237 DWORD n = 0;
00238 if (!WriteFile(h, buf, size, &n, NULL)) n = 0;
00239 return n;
00240 }
00241
00242
00243
00244 BOOL CreateChildProcess(DWORD *pid, const char *cmd, HANDLE in, HANDLE out, HANDLE err)
00245 {
00246 PROCESS_INFORMATION pi;
00247 STARTUPINFO si;
00248
00249 ZeroMemory(&si, sizeof(STARTUPINFO));
00250 si.cb = sizeof(STARTUPINFO);
00251 si.dwFlags = STARTF_USESTDHANDLES;
00252 si.hStdInput = in;
00253 si.hStdOutput = out;
00254 si.hStdError = err;
00255
00256 TCHAR shellCmd[_MAX_PATH];
00257 strcpy(shellCmd, cmd);
00258 BOOL ret = CreateProcess(NULL, shellCmd, NULL, NULL, TRUE, 0,
00259 NULL, NULL, &si, &pi);
00260
00261 if (ret) *pid = pi.dwProcessId;
00262 return ret;
00263 }
00264
00265 static HANDLE myPID = NULL;
00266
00267 int sys_ipc_exec(ht_streamfile **in, ht_streamfile **out, ht_streamfile **err, int *handle, const char *cmd, int options)
00268 {
00269 if (myPID != NULL) return EBUSY;
00270 HANDLE old_out = GetStdHandle(STD_OUTPUT_HANDLE);
00271 HANDLE outr, outw, outr_dup;
00272 if (!CreatePipe(&outr, &outw, NULL, 0)) return EIO;
00273 if (!SetStdHandle(STD_OUTPUT_HANDLE, outw)) return EIO;
00274 if (!DuplicateHandle(GetCurrentProcess(), outr, GetCurrentProcess(),
00275 &outr_dup, 0, FALSE, DUPLICATE_SAME_ACCESS)) return EIO;
00276 CloseHandle(outr);
00277
00278 HANDLE old_in = GetStdHandle(STD_INPUT_HANDLE);
00279 HANDLE inr, inw, inw_dup;
00280 if (!CreatePipe(&inr, &inw, NULL, 0)) return EIO;
00281 if (!SetStdHandle(STD_INPUT_HANDLE, inr)) return EIO;
00282 if (!DuplicateHandle(GetCurrentProcess(), inw, GetCurrentProcess(),
00283 &inw_dup, 0, FALSE, DUPLICATE_SAME_ACCESS)) return EIO;
00284 CloseHandle(inw);
00285
00286 DWORD child_pid;
00287 if (!CreateChildProcess(&child_pid, cmd, inr, outw, outw))
00288 return EIO;
00289
00290 SetStdHandle(STD_OUTPUT_HANDLE, old_out);
00291 SetStdHandle(STD_INPUT_HANDLE, old_in);
00292
00293 HANDLE ph = OpenProcess(PROCESS_ALL_ACCESS, false, child_pid);
00294 if (ph == NULL) return EIO;
00295
00296 myPID = ph;
00297 *handle = (int)ph;
00298
00299 ht_win32_file *wf;
00300
00301 wf = new ht_win32_file();
00302 wf->init(inw_dup);
00303 *in = wf;
00304
00305 wf = new ht_win32_file();
00306 wf->init(outr_dup);
00307 *out = wf;
00308
00309 wf = new ht_win32_file();
00310 wf->init(outr_dup);
00311 *err = wf;
00312
00313 return 0;
00314 }
00315
00316 bool sys_ipc_is_valid(int handle)
00317 {
00318 HANDLE h = (HANDLE)handle;
00319 if (h == myPID) {
00320 return (WaitForSingleObject(h, 0) != WAIT_OBJECT_0);
00321 }
00322 return false;
00323 }
00324
00325 int sys_ipc_terminate(int handle)
00326 {
00327 if (sys_ipc_is_valid(handle)) {
00328 HANDLE h = (HANDLE)handle;
00329 int r = (TerminateProcess(h, 1)) ? 0 : EIO;
00330 CloseHandle(h);
00331 myPID = NULL;
00332 return r;
00333 }
00334 myPID = NULL;
00335 return EINVAL;
00336 }
00337
00338 int sys_get_caps()
00339 {
00340 return SYSCAP_NONBLOCKING_IPC;
00341 }
00342
00343 bool sys_write_data_to_native_clipboard(const void *data, int size)
00344 {
00345 if (!OpenClipboard(NULL)) return false;
00346 HANDLE h = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
00347 if (!h) {
00348 CloseClipboard();
00349 return false;
00350 }
00351 void *mem = GlobalLock(h);
00352 memmove(mem, data, size);
00353 GlobalUnlock(h);
00354 SetClipboardData(CF_OEMTEXT, h);
00355 CloseClipboard();
00356 }
00357
00358 int sys_get_native_clipboard_data_size()
00359 {
00360 if (!OpenClipboard(NULL)) return false;
00361 HANDLE h = GetClipboardData(CF_OEMTEXT);
00362 int len = 0;
00363 if (h) {
00364 void *mem = GlobalLock(h);
00365 len = strlen((char*)mem);
00366 GlobalUnlock(h);
00367 }
00368 CloseClipboard();
00369 return len;
00370 }
00371
00372 bool sys_read_data_from_native_clipboard(void *data, int max_size)
00373 {
00374 if (!OpenClipboard(NULL)) return false;
00375 HANDLE h = GetClipboardData(CF_OEMTEXT);
00376 if (h) {
00377 void *mem = GlobalLock(h);
00378 ht_snprintf((char*)data, max_size, "%s", mem);
00379 GlobalUnlock(h);
00380 }
00381 CloseClipboard();
00382 return h != NULL;
00383 }
00384
00385
00386
00387
00388
00389
00390 bool init_system()
00391 {
00392 return true;
00393 }
00394
00395
00396
00397
00398
00399 void done_system()
00400 {
00401 }
00402