18ccd4a63SDavid du Colombier #include <windows.h> 28ccd4a63SDavid du Colombier #include "u.h" 38ccd4a63SDavid du Colombier #include "lib.h" 48ccd4a63SDavid du Colombier #include "dat.h" 58ccd4a63SDavid du Colombier #include "fns.h" 68ccd4a63SDavid du Colombier #include <libsec.h> 78ccd4a63SDavid du Colombier 88ccd4a63SDavid du Colombier typedef struct Oproc Oproc; 98ccd4a63SDavid du Colombier struct Oproc { 108ccd4a63SDavid du Colombier int tid; 118ccd4a63SDavid du Colombier HANDLE *sema; 128ccd4a63SDavid du Colombier }; 138ccd4a63SDavid du Colombier 148ccd4a63SDavid du Colombier static int tlsx = TLS_OUT_OF_INDEXES; 158ccd4a63SDavid du Colombier 168ccd4a63SDavid du Colombier char *argv0; 178ccd4a63SDavid du Colombier 188ccd4a63SDavid du Colombier Proc* 198ccd4a63SDavid du Colombier _getproc(void) 208ccd4a63SDavid du Colombier { 218ccd4a63SDavid du Colombier if(tlsx == TLS_OUT_OF_INDEXES) 228ccd4a63SDavid du Colombier return nil; 238ccd4a63SDavid du Colombier return TlsGetValue(tlsx); 248ccd4a63SDavid du Colombier } 258ccd4a63SDavid du Colombier 268ccd4a63SDavid du Colombier void 278ccd4a63SDavid du Colombier _setproc(Proc *p) 288ccd4a63SDavid du Colombier { 298ccd4a63SDavid du Colombier if(tlsx == TLS_OUT_OF_INDEXES){ 308ccd4a63SDavid du Colombier tlsx = TlsAlloc(); 318ccd4a63SDavid du Colombier if(tlsx == TLS_OUT_OF_INDEXES) 328ccd4a63SDavid du Colombier panic("out of indexes"); 338ccd4a63SDavid du Colombier } 348ccd4a63SDavid du Colombier TlsSetValue(tlsx, p); 358ccd4a63SDavid du Colombier } 368ccd4a63SDavid du Colombier 378ccd4a63SDavid du Colombier void 388ccd4a63SDavid du Colombier oserror(void) 398ccd4a63SDavid du Colombier { 408ccd4a63SDavid du Colombier oserrstr(); 418ccd4a63SDavid du Colombier nexterror(); 428ccd4a63SDavid du Colombier } 438ccd4a63SDavid du Colombier 448ccd4a63SDavid du Colombier void 458ccd4a63SDavid du Colombier osinit(void) 468ccd4a63SDavid du Colombier { 478ccd4a63SDavid du Colombier Oproc *t; 488ccd4a63SDavid du Colombier static Proc firstprocCTstore; 498ccd4a63SDavid du Colombier 508ccd4a63SDavid du Colombier _setproc(&firstprocCTstore); 518ccd4a63SDavid du Colombier t = (Oproc*)firstprocCTstore.oproc; 528ccd4a63SDavid du Colombier assert(t != 0); 538ccd4a63SDavid du Colombier 548ccd4a63SDavid du Colombier t->tid = GetCurrentThreadId(); 558ccd4a63SDavid du Colombier t->sema = CreateSemaphore(0, 0, 1000, 0); 568ccd4a63SDavid du Colombier if(t->sema == 0) { 578ccd4a63SDavid du Colombier oserror(); 588ccd4a63SDavid du Colombier panic("could not create semaphore: %r"); 598ccd4a63SDavid du Colombier } 608ccd4a63SDavid du Colombier } 618ccd4a63SDavid du Colombier 628ccd4a63SDavid du Colombier void 638ccd4a63SDavid du Colombier osnewproc(Proc *p) 648ccd4a63SDavid du Colombier { 658ccd4a63SDavid du Colombier Oproc *op; 668ccd4a63SDavid du Colombier 678ccd4a63SDavid du Colombier op = (Oproc*)p->oproc; 688ccd4a63SDavid du Colombier op->sema = CreateSemaphore(0, 0, 1000, 0); 698ccd4a63SDavid du Colombier if (op->sema == 0) { 708ccd4a63SDavid du Colombier oserror(); 718ccd4a63SDavid du Colombier panic("could not create semaphore: %r"); 728ccd4a63SDavid du Colombier } 738ccd4a63SDavid du Colombier } 748ccd4a63SDavid du Colombier 758ccd4a63SDavid du Colombier void 768ccd4a63SDavid du Colombier osmsleep(int ms) 778ccd4a63SDavid du Colombier { 788ccd4a63SDavid du Colombier Sleep((DWORD) ms); 798ccd4a63SDavid du Colombier } 808ccd4a63SDavid du Colombier 818ccd4a63SDavid du Colombier void 828ccd4a63SDavid du Colombier osyield(void) 838ccd4a63SDavid du Colombier { 848ccd4a63SDavid du Colombier Sleep(0); 858ccd4a63SDavid du Colombier } 868ccd4a63SDavid du Colombier 878ccd4a63SDavid du Colombier static DWORD WINAPI tramp(LPVOID vp); 888ccd4a63SDavid du Colombier 898ccd4a63SDavid du Colombier void 908ccd4a63SDavid du Colombier osproc(Proc *p) 918ccd4a63SDavid du Colombier { 928ccd4a63SDavid du Colombier DWORD tid; 938ccd4a63SDavid du Colombier 948ccd4a63SDavid du Colombier if(CreateThread(0, 0, tramp, p, 0, &tid) == 0) { 958ccd4a63SDavid du Colombier oserror(); 968ccd4a63SDavid du Colombier panic("osproc: %r"); 978ccd4a63SDavid du Colombier } 988ccd4a63SDavid du Colombier 998ccd4a63SDavid du Colombier Sleep(0); 1008ccd4a63SDavid du Colombier } 1018ccd4a63SDavid du Colombier 1028ccd4a63SDavid du Colombier static DWORD WINAPI 1038ccd4a63SDavid du Colombier tramp(LPVOID vp) 1048ccd4a63SDavid du Colombier { 1058ccd4a63SDavid du Colombier Proc *p = (Proc *) vp; 1068ccd4a63SDavid du Colombier Oproc *op = (Oproc*) p->oproc; 1078ccd4a63SDavid du Colombier 1088ccd4a63SDavid du Colombier _setproc(p); 1098ccd4a63SDavid du Colombier op->tid = GetCurrentThreadId(); 1108ccd4a63SDavid du Colombier op->sema = CreateSemaphore(0, 0, 1000, 0); 1118ccd4a63SDavid du Colombier if(op->sema == 0) { 1128ccd4a63SDavid du Colombier oserror(); 1138ccd4a63SDavid du Colombier panic("could not create semaphore: %r"); 1148ccd4a63SDavid du Colombier } 1158ccd4a63SDavid du Colombier 1168ccd4a63SDavid du Colombier (*p->fn)(p->arg); 1178ccd4a63SDavid du Colombier ExitThread(0); 1188ccd4a63SDavid du Colombier return 0; 1198ccd4a63SDavid du Colombier } 1208ccd4a63SDavid du Colombier 1218ccd4a63SDavid du Colombier void 1228ccd4a63SDavid du Colombier procsleep(void) 1238ccd4a63SDavid du Colombier { 1248ccd4a63SDavid du Colombier Proc *p; 1258ccd4a63SDavid du Colombier Oproc *op; 1268ccd4a63SDavid du Colombier 1278ccd4a63SDavid du Colombier p = up; 1288ccd4a63SDavid du Colombier op = (Oproc*)p->oproc; 1298ccd4a63SDavid du Colombier WaitForSingleObject(op->sema, INFINITE);} 1308ccd4a63SDavid du Colombier 1318ccd4a63SDavid du Colombier void 1328ccd4a63SDavid du Colombier procwakeup(Proc *p) 1338ccd4a63SDavid du Colombier { 1348ccd4a63SDavid du Colombier Oproc *op; 1358ccd4a63SDavid du Colombier 1368ccd4a63SDavid du Colombier op = (Oproc*)p->oproc; 1378ccd4a63SDavid du Colombier ReleaseSemaphore(op->sema, 1, 0); 1388ccd4a63SDavid du Colombier } 1398ccd4a63SDavid du Colombier 1408ccd4a63SDavid du Colombier void 1418ccd4a63SDavid du Colombier random20(uchar *p) 1428ccd4a63SDavid du Colombier { 1438ccd4a63SDavid du Colombier LARGE_INTEGER ti; 1448ccd4a63SDavid du Colombier int i, j; 1458ccd4a63SDavid du Colombier FILETIME ft; 1468ccd4a63SDavid du Colombier DigestState ds; 1478ccd4a63SDavid du Colombier vlong tsc; 1488ccd4a63SDavid du Colombier 1498ccd4a63SDavid du Colombier GetSystemTimeAsFileTime(&ft); 1508ccd4a63SDavid du Colombier memset(&ds, 0, sizeof ds); 1518ccd4a63SDavid du Colombier sha1((uchar*)&ft, sizeof(ft), 0, &ds); 1528ccd4a63SDavid du Colombier for(i=0; i<50; i++) { 1538ccd4a63SDavid du Colombier for(j=0; j<10; j++) { 1548ccd4a63SDavid du Colombier QueryPerformanceCounter(&ti); 1558ccd4a63SDavid du Colombier sha1((uchar*)&ti, sizeof(ti), 0, &ds); 1568ccd4a63SDavid du Colombier tsc = GetTickCount(); 1578ccd4a63SDavid du Colombier sha1((uchar*)&tsc, sizeof(tsc), 0, &ds); 1588ccd4a63SDavid du Colombier } 1598ccd4a63SDavid du Colombier Sleep(10); 1608ccd4a63SDavid du Colombier } 1618ccd4a63SDavid du Colombier sha1(0, 0, p, &ds); 1628ccd4a63SDavid du Colombier } 1638ccd4a63SDavid du Colombier 1648ccd4a63SDavid du Colombier void 1658ccd4a63SDavid du Colombier randominit(void) 1668ccd4a63SDavid du Colombier { 1678ccd4a63SDavid du Colombier } 1688ccd4a63SDavid du Colombier 1698ccd4a63SDavid du Colombier ulong 1708ccd4a63SDavid du Colombier randomread(void *v, ulong n) 1718ccd4a63SDavid du Colombier { 1728ccd4a63SDavid du Colombier int i; 1738ccd4a63SDavid du Colombier uchar p[20]; 1748ccd4a63SDavid du Colombier 1758ccd4a63SDavid du Colombier for(i=0; i<n; i+=20){ 1768ccd4a63SDavid du Colombier random20(p); 1778ccd4a63SDavid du Colombier if(i+20 <= n) 1788ccd4a63SDavid du Colombier memmove((char*)v+i, p, 20); 1798ccd4a63SDavid du Colombier else 1808ccd4a63SDavid du Colombier memmove((char*)v+i, p, n-i); 1818ccd4a63SDavid du Colombier } 1828ccd4a63SDavid du Colombier return n; 1838ccd4a63SDavid du Colombier } 1848ccd4a63SDavid du Colombier 1858ccd4a63SDavid du Colombier long 1868ccd4a63SDavid du Colombier seconds(void) 1878ccd4a63SDavid du Colombier { 1888ccd4a63SDavid du Colombier return time(0); 1898ccd4a63SDavid du Colombier } 1908ccd4a63SDavid du Colombier 1918ccd4a63SDavid du Colombier ulong 1928ccd4a63SDavid du Colombier ticks(void) 1938ccd4a63SDavid du Colombier { 1948ccd4a63SDavid du Colombier return GetTickCount(); 1958ccd4a63SDavid du Colombier } 1968ccd4a63SDavid du Colombier 1978ccd4a63SDavid du Colombier #if 0 1988ccd4a63SDavid du Colombier uvlong 1998ccd4a63SDavid du Colombier fastticks(uvlong *v) 2008ccd4a63SDavid du Colombier { 2018ccd4a63SDavid du Colombier uvlong n; 2028ccd4a63SDavid du Colombier 2038ccd4a63SDavid du Colombier n = GetTickCount() * 1000 * 1000; 2048ccd4a63SDavid du Colombier if(v) 2058ccd4a63SDavid du Colombier *v = n; 2068ccd4a63SDavid du Colombier return n; 2078ccd4a63SDavid du Colombier } 2088ccd4a63SDavid du Colombier #endif 2098ccd4a63SDavid du Colombier 2108ccd4a63SDavid du Colombier extern int main(int, char*[]); 2118ccd4a63SDavid du Colombier 2128ccd4a63SDavid du Colombier 2138ccd4a63SDavid du Colombier int 2148ccd4a63SDavid du Colombier wstrutflen(Rune *s) 2158ccd4a63SDavid du Colombier { 2168ccd4a63SDavid du Colombier int n; 2178ccd4a63SDavid du Colombier 2188ccd4a63SDavid du Colombier for(n=0; *s; n+=runelen(*s),s++) 2198ccd4a63SDavid du Colombier ; 2208ccd4a63SDavid du Colombier return n; 2218ccd4a63SDavid du Colombier } 2228ccd4a63SDavid du Colombier 2238ccd4a63SDavid du Colombier int 2248ccd4a63SDavid du Colombier wstrtoutf(char *s, Rune *t, int n) 2258ccd4a63SDavid du Colombier { 2268ccd4a63SDavid du Colombier int i; 2278ccd4a63SDavid du Colombier char *s0; 2288ccd4a63SDavid du Colombier 2298ccd4a63SDavid du Colombier s0 = s; 2308ccd4a63SDavid du Colombier if(n <= 0) 2318ccd4a63SDavid du Colombier return wstrutflen(t)+1; 2328ccd4a63SDavid du Colombier while(*t) { 2338ccd4a63SDavid du Colombier if(n < UTFmax+1 && n < runelen(*t)+1) { 2348ccd4a63SDavid du Colombier *s = 0; 2358ccd4a63SDavid du Colombier return s-s0+wstrutflen(t)+1; 2368ccd4a63SDavid du Colombier } 2378ccd4a63SDavid du Colombier i = runetochar(s, t); 2388ccd4a63SDavid du Colombier s += i; 2398ccd4a63SDavid du Colombier n -= i; 2408ccd4a63SDavid du Colombier t++; 2418ccd4a63SDavid du Colombier } 2428ccd4a63SDavid du Colombier *s = 0; 2438ccd4a63SDavid du Colombier return s-s0; 2448ccd4a63SDavid du Colombier } 2458ccd4a63SDavid du Colombier 2468ccd4a63SDavid du Colombier int 2478ccd4a63SDavid du Colombier win_hasunicode(void) 2488ccd4a63SDavid du Colombier { 2498ccd4a63SDavid du Colombier OSVERSIONINFOA osinfo; 2508ccd4a63SDavid du Colombier int r; 2518ccd4a63SDavid du Colombier 2528ccd4a63SDavid du Colombier osinfo.dwOSVersionInfoSize = sizeof(osinfo); 2538ccd4a63SDavid du Colombier if(!GetVersionExA(&osinfo)) 2548ccd4a63SDavid du Colombier panic("GetVersionEx failed"); 2558ccd4a63SDavid du Colombier switch(osinfo.dwPlatformId) { 2568ccd4a63SDavid du Colombier default: 2578ccd4a63SDavid du Colombier panic("unknown PlatformId"); 2588ccd4a63SDavid du Colombier case VER_PLATFORM_WIN32s: 2598ccd4a63SDavid du Colombier panic("Win32s not supported"); 2608ccd4a63SDavid du Colombier case VER_PLATFORM_WIN32_WINDOWS: 2618ccd4a63SDavid du Colombier r = 0; 2628ccd4a63SDavid du Colombier break; 2638ccd4a63SDavid du Colombier case VER_PLATFORM_WIN32_NT: 2648ccd4a63SDavid du Colombier r = 1; 2658ccd4a63SDavid du Colombier break; 2668ccd4a63SDavid du Colombier } 2678ccd4a63SDavid du Colombier 2688ccd4a63SDavid du Colombier return r; 2698ccd4a63SDavid du Colombier } 2708ccd4a63SDavid du Colombier 2718ccd4a63SDavid du Colombier int 2728ccd4a63SDavid du Colombier wstrlen(Rune *s) 2738ccd4a63SDavid du Colombier { 2748ccd4a63SDavid du Colombier int n; 2758ccd4a63SDavid du Colombier 2768ccd4a63SDavid du Colombier for(n=0; *s; s++,n++) 2778ccd4a63SDavid du Colombier ; 2788ccd4a63SDavid du Colombier return n; 2798ccd4a63SDavid du Colombier } 2808ccd4a63SDavid du Colombier static int args(char *argv[], int n, char *p); 2818ccd4a63SDavid du Colombier 2828ccd4a63SDavid du Colombier int APIENTRY 2838ccd4a63SDavid du Colombier WinMain(HINSTANCE x, HINSTANCE y, LPSTR z, int w) 2848ccd4a63SDavid du Colombier { 2858ccd4a63SDavid du Colombier int argc, n; 2868ccd4a63SDavid du Colombier char *arg, *p, **argv; 2878ccd4a63SDavid du Colombier Rune *warg; 2888ccd4a63SDavid du Colombier 2898ccd4a63SDavid du Colombier if(0 && win_hasunicode()){ 2908ccd4a63SDavid du Colombier warg = GetCommandLineW(); 2918ccd4a63SDavid du Colombier n = (wstrlen(warg)+1)*UTFmax; 2928ccd4a63SDavid du Colombier arg = malloc(n); 2938ccd4a63SDavid du Colombier wstrtoutf(arg, warg, n); 2948ccd4a63SDavid du Colombier }else 2958ccd4a63SDavid du Colombier arg = GetCommandLineA(); 2968ccd4a63SDavid du Colombier 2978ccd4a63SDavid du Colombier /* conservative guess at the number of args */ 2988ccd4a63SDavid du Colombier for(argc=4,p=arg; *p; p++) 2998ccd4a63SDavid du Colombier if(*p == ' ' || *p == '\t') 3008ccd4a63SDavid du Colombier argc++; 3018ccd4a63SDavid du Colombier argv = malloc(argc*sizeof(char*)); 3028ccd4a63SDavid du Colombier argc = args(argv, argc, arg); 3038ccd4a63SDavid du Colombier 3048ccd4a63SDavid du Colombier mymain(argc, argv); 3058ccd4a63SDavid du Colombier ExitThread(0); 3068ccd4a63SDavid du Colombier return 0; 3078ccd4a63SDavid du Colombier } 3088ccd4a63SDavid du Colombier 3098ccd4a63SDavid du Colombier /* 3108ccd4a63SDavid du Colombier * Break the command line into arguments 3118ccd4a63SDavid du Colombier * The rules for this are not documented but appear to be the following 3128ccd4a63SDavid du Colombier * according to the source for the microsoft C library. 3138ccd4a63SDavid du Colombier * Words are seperated by space or tab 3148ccd4a63SDavid du Colombier * Words containing a space or tab can be quoted using " 3158ccd4a63SDavid du Colombier * 2N backslashes + " ==> N backslashes and end quote 3168ccd4a63SDavid du Colombier * 2N+1 backslashes + " ==> N backslashes + literal " 3178ccd4a63SDavid du Colombier * N backslashes not followed by " ==> N backslashes 3188ccd4a63SDavid du Colombier */ 3198ccd4a63SDavid du Colombier static int 3208ccd4a63SDavid du Colombier args(char *argv[], int n, char *p) 3218ccd4a63SDavid du Colombier { 3228ccd4a63SDavid du Colombier char *p2; 3238ccd4a63SDavid du Colombier int i, j, quote, nbs; 3248ccd4a63SDavid du Colombier 3258ccd4a63SDavid du Colombier for(i=0; *p && i<n-1; i++) { 3268ccd4a63SDavid du Colombier while(*p == ' ' || *p == '\t') 3278ccd4a63SDavid du Colombier p++; 3288ccd4a63SDavid du Colombier quote = 0; 3298ccd4a63SDavid du Colombier argv[i] = p2 = p; 3308ccd4a63SDavid du Colombier for(;*p; p++) { 3318ccd4a63SDavid du Colombier if(!quote && (*p == ' ' || *p == '\t')) 3328ccd4a63SDavid du Colombier break; 3338ccd4a63SDavid du Colombier for(nbs=0; *p == '\\'; p++,nbs++) 3348ccd4a63SDavid du Colombier ; 3358ccd4a63SDavid du Colombier if(*p == '"') { 3368ccd4a63SDavid du Colombier for(j=0; j<(nbs>>1); j++) 3378ccd4a63SDavid du Colombier *p2++ = '\\'; 3388ccd4a63SDavid du Colombier if(nbs&1) 3398ccd4a63SDavid du Colombier *p2++ = *p; 3408ccd4a63SDavid du Colombier else 3418ccd4a63SDavid du Colombier quote = !quote; 3428ccd4a63SDavid du Colombier } else { 3438ccd4a63SDavid du Colombier for(j=0; j<nbs; j++) 3448ccd4a63SDavid du Colombier *p2++ = '\\'; 3458ccd4a63SDavid du Colombier *p2++ = *p; 3468ccd4a63SDavid du Colombier } 3478ccd4a63SDavid du Colombier } 3488ccd4a63SDavid du Colombier /* move p up one to avoid pointing to null at end of p2 */ 3498ccd4a63SDavid du Colombier if(*p) 3508ccd4a63SDavid du Colombier p++; 3518ccd4a63SDavid du Colombier *p2 = 0; 3528ccd4a63SDavid du Colombier } 3538ccd4a63SDavid du Colombier argv[i] = 0; 3548ccd4a63SDavid du Colombier 3558ccd4a63SDavid du Colombier return i; 3568ccd4a63SDavid du Colombier } 3578ccd4a63SDavid du Colombier /* 3588ccd4a63SDavid du Colombier * Windows socket error messages 3598ccd4a63SDavid du Colombier * There must be a way to get these strings out of the library. 3608ccd4a63SDavid du Colombier * This table is derived from the MSDN online help. 3618ccd4a63SDavid du Colombier */ 3628ccd4a63SDavid du Colombier static struct { 3638ccd4a63SDavid du Colombier int e; 3648ccd4a63SDavid du Colombier char *s; 3658ccd4a63SDavid du Colombier } tab[] = { 3668ccd4a63SDavid du Colombier { 10004, "interrupted function call" }, 3678ccd4a63SDavid du Colombier { 10013, "permission denied" }, 3688ccd4a63SDavid du Colombier { 10014, "bad address" }, 3698ccd4a63SDavid du Colombier { 10022, "invalid argument" }, 3708ccd4a63SDavid du Colombier { 10024, "too many open files" }, 3718ccd4a63SDavid du Colombier { 10035, "resource temporarily unavailable" }, 3728ccd4a63SDavid du Colombier { 10036, "operation now in progress" }, 3738ccd4a63SDavid du Colombier { 10037, "operation already in progress" }, 3748ccd4a63SDavid du Colombier { 10038, "socket operation on nonsocket" }, 3758ccd4a63SDavid du Colombier { 10039, "destination address required" }, 3768ccd4a63SDavid du Colombier { 10040, "message too long" }, 3778ccd4a63SDavid du Colombier { 10041, "protocol wrong type for socket" }, 3788ccd4a63SDavid du Colombier { 10042, "bad protocol option" }, 3798ccd4a63SDavid du Colombier { 10043, "protocol not supported" }, 3808ccd4a63SDavid du Colombier { 10044, "socket type not supported" }, 3818ccd4a63SDavid du Colombier { 10045, "operation not supported" }, 3828ccd4a63SDavid du Colombier { 10046, "protocol family not supported" }, 3838ccd4a63SDavid du Colombier { 10047, "address family not supported by protocol family" }, 3848ccd4a63SDavid du Colombier { 10048, "address already in use" }, 3858ccd4a63SDavid du Colombier { 10049, "cannot assign requested address" }, 3868ccd4a63SDavid du Colombier { 10050, "network is down" }, 3878ccd4a63SDavid du Colombier { 10051, "network is unreachable" }, 3888ccd4a63SDavid du Colombier { 10052, "network dropped connection on reset" }, 3898ccd4a63SDavid du Colombier { 10053, "software caused connection abort" }, 3908ccd4a63SDavid du Colombier { 10054, "connection reset by peer" }, 3918ccd4a63SDavid du Colombier { 10055, "no buffer space available" }, 3928ccd4a63SDavid du Colombier { 10056, "socket is already connected" }, 3938ccd4a63SDavid du Colombier { 10057, "socket is not connected" }, 3948ccd4a63SDavid du Colombier { 10058, "cannot send after socket shutdown" }, 3958ccd4a63SDavid du Colombier { 10060, "connection timed out" }, 3968ccd4a63SDavid du Colombier { 10061, "connection refused" }, 3978ccd4a63SDavid du Colombier { 10064, "host is down" }, 3988ccd4a63SDavid du Colombier { 10065, "no route to host" }, 3998ccd4a63SDavid du Colombier { 10067, "too many processes" }, 4008ccd4a63SDavid du Colombier { 10091, "network subsystem is unavailable" }, 4018ccd4a63SDavid du Colombier { 10092, "winsock.dll version out of range" }, 4028ccd4a63SDavid du Colombier { 10093, "wsastartup not called" }, 4038ccd4a63SDavid du Colombier { 10101, "graceful shutdown in progress" }, 4048ccd4a63SDavid du Colombier { 10109, "class type not found" }, 4058ccd4a63SDavid du Colombier { 11001, "host name not found" }, 4068ccd4a63SDavid du Colombier { 11002, "host not found (non-authoritative)" }, 4078ccd4a63SDavid du Colombier { 11003, "nonrecoverable error" }, 4088ccd4a63SDavid du Colombier { 11004, "valid name, but no data record of requested type" }, 4098ccd4a63SDavid du Colombier }; 4108ccd4a63SDavid du Colombier 4118ccd4a63SDavid du Colombier void 4128ccd4a63SDavid du Colombier osrerrstr(char *buf, uint nbuf) 4138ccd4a63SDavid du Colombier { 4148ccd4a63SDavid du Colombier char *p, *q; 4158ccd4a63SDavid du Colombier int e, i, r; 4168ccd4a63SDavid du Colombier 4178ccd4a63SDavid du Colombier e = GetLastError(); 4188ccd4a63SDavid du Colombier r = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 4198ccd4a63SDavid du Colombier 0, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 4208ccd4a63SDavid du Colombier buf, nbuf, 0); 4218ccd4a63SDavid du Colombier if(r == 0){ 4228ccd4a63SDavid du Colombier for(i=0; i<nelem(tab); i++) 4238ccd4a63SDavid du Colombier if(tab[i].e == e){ 4248ccd4a63SDavid du Colombier strecpy(buf, buf+nbuf, tab[i].s); 4258ccd4a63SDavid du Colombier break; 4268ccd4a63SDavid du Colombier } 4278ccd4a63SDavid du Colombier if(i==nelem(tab)) 4288ccd4a63SDavid du Colombier snprint(buf, nbuf, "windows error %d", e); 4298ccd4a63SDavid du Colombier } 4308ccd4a63SDavid du Colombier 4318ccd4a63SDavid du Colombier for(p=q=buf; *p; p++) { 4328ccd4a63SDavid du Colombier if(*p == '\r') 4338ccd4a63SDavid du Colombier continue; 4348ccd4a63SDavid du Colombier if(*p == '\n') 4358ccd4a63SDavid du Colombier *q++ = ' '; 4368ccd4a63SDavid du Colombier else 4378ccd4a63SDavid du Colombier *q++ = *p; 4388ccd4a63SDavid du Colombier } 4398ccd4a63SDavid du Colombier *q = '\0'; 4408ccd4a63SDavid du Colombier } 4418ccd4a63SDavid du Colombier 4428ccd4a63SDavid du Colombier void 4438ccd4a63SDavid du Colombier oserrstr(void) 4448ccd4a63SDavid du Colombier { 4458ccd4a63SDavid du Colombier osrerrstr(up->errstr, ERRMAX); 4468ccd4a63SDavid du Colombier } 447*ec59a3ddSDavid du Colombier 448*ec59a3ddSDavid du Colombier long 449*ec59a3ddSDavid du Colombier showfilewrite(char *a, int n) 450*ec59a3ddSDavid du Colombier { 451*ec59a3ddSDavid du Colombier Rune *action, *arg, *cmd; 452*ec59a3ddSDavid du Colombier static Rune Lopen[] = { 'o', 'p', 'e', 'n', 0 }; 453*ec59a3ddSDavid du Colombier 454*ec59a3ddSDavid du Colombier cmd = runesmprint("%.*s", n, a); 455*ec59a3ddSDavid du Colombier if(cmd == nil) 456*ec59a3ddSDavid du Colombier error("out of memory"); 457*ec59a3ddSDavid du Colombier if(cmd[runestrlen(cmd)-1] == '\n') 458*ec59a3ddSDavid du Colombier cmd[runestrlen(cmd)] = 0; 459*ec59a3ddSDavid du Colombier p = runestrchr(cmd, ' '); 460*ec59a3ddSDavid du Colombier if(p){ 461*ec59a3ddSDavid du Colombier action = cmd; 462*ec59a3ddSDavid du Colombier *p++ = 0; 463*ec59a3ddSDavid du Colombier arg = p; 464*ec59a3ddSDavid du Colombier }else{ 465*ec59a3ddSDavid du Colombier action = Lopen; 466*ec59a3ddSDavid du Colombier arg = cmd; 467*ec59a3ddSDavid du Colombier } 468*ec59a3ddSDavid du Colombier ShellExecute(0, 0, action, arg, 0, SW_SHOWNORMAL); 469*ec59a3ddSDavid du Colombier return n; 470*ec59a3ddSDavid du Colombier } 471