Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

htsys.cc

Go to the documentation of this file.
00001 /* 
00002  *      HT Editor
00003  *      htsys.cc (WIN32 implementation)
00004  *
00005  *      Copyright (C) 1999-2002 Sebastian Biallas (sb@web-productions.de)
00006  *      Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de)
00007  *
00008  *      This program is free software; you can redistribute it and/or modify
00009  *      it under the terms of the GNU General Public License version 2 as
00010  *      published by the Free Software Foundation.
00011  *
00012  *      This program is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU General Public License
00018  *      along with this program; if not, write to the Free Software
00019  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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);         // 100 nano-sec to full sec
00055         return QWORD_GET_LO(q) + 1240431886;    // MAGIC: this is 1.1.1970 minus 1.1.1601 in seconds
00056 }
00057 
00058 void sys_findfill(pfind_t *pfind)
00059 {
00060         /*DWORD dwFileAttributes;
00061         FILETIME ftCreationTime;
00062         FILETIME ftLastAccessTime;
00063         FILETIME ftLastWriteTime;
00064         DWORD    nFileSizeHigh;
00065         DWORD    nFileSizeLow;
00066         DWORD    dwReserved0;
00067         DWORD    dwReserved1;
00068         TCHAR    cFileName[ MAX_PATH ];
00069         TCHAR    cAlternateFileName[ 14 ];*/
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  *      Win32 IPC
00205  */
00206 
00207 class ht_win32_file: public ht_streamfile {
00208 private:
00209         HANDLE h;
00210 public:
00211                    void init(HANDLE h);
00212 /* overwritten */
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/*DETACHED_PROCESS*/,
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  *      INIT
00388  */
00389 
00390 bool init_system()
00391 {
00392         return true;
00393 }
00394 
00395 /*
00396  *      DONE
00397  */
00398 
00399 void done_system()
00400 {
00401 }
00402 

Generated on Fri May 7 21:15:37 2004 by doxygen 1.3.5