#include "config.h" #include "mpg123app.h" #include "common/debug.h" #ifdef WANT_WIN32_UNICODE /* Obscure and undocumented call from MS C Runtime "MSVCRT.DLL" */ typedef struct { int newmode; } _startupinfo; /* XP and later has an int return though */ void __cdecl __declspec(dllimport) __wgetmainargs ( int *_Argc, wchar_t ***_Argv, wchar_t ***_Env, int _DoWildCard, _startupinfo * _StartInfo ); int win32_cmdline_utf8(int * argc, char *** argv) { int argcounter; wchar_t **argv_wide; wchar_t **env; char *argvptr; _startupinfo startup; /* That's too lame. */ if(argv == NULL || argc == NULL) return -1; startup.newmode = 0; __wgetmainargs(argc, &argv_wide,&env,1, &startup); *argv = (char **)calloc(sizeof (char *), *argc); if(*argv == NULL){ error("Cannot allocate memory for command line."); return -1; } for(argcounter = 0; argcounter < *argc; argcounter++) { INT123_win32_wide_utf8(argv_wide[argcounter], &argvptr, NULL); (*argv)[argcounter] = argvptr; } return 0; } void win32_cmdline_free(int argc, char **argv) { int i; if(argv == NULL) return; for(i=0; i available) ? available : nbyte; debug("Starting ReadFileEx"); check = ReadFileEx(fifohandle,buf,readbuff,&ov1,&ReadComplete); WaitForSingleObjectEx(fifohandle,INFINITE,TRUE); debug1("Read %ld bytes from pipe", readbuff); return (!check) ? 0 : readbuff; } /* function should be able to tell if bytes are available and return immediately on overlapped asynchrounous pipes, like unix select() */ DWORD win32_fifo_read_peek(struct timeval *tv) { DWORD ret = 0; DWORD err, timer; timer = (tv) ? tv -> tv_sec * 1000 : INFINITE; debug1("Peeking on pipe handle %p", fifohandle); SetLastError(0); if(!fifohandle) return 0; PeekNamedPipe(fifohandle, NULL, 0, NULL, &ret, NULL); err = GetLastError(); debug1("Waiting %ld msec for pipe to be ready", timer); debug1("GetLastError was %ld", err); if(err == ERROR_BROKEN_PIPE) { debug("Broken pipe, disconnecting"); DisconnectNamedPipe(fifohandle); ConnectNamedPipe(fifohandle,&ov1); WaitForSingleObjectEx(fifohandle,timer,TRUE); } else if(err == ERROR_BAD_PIPE) { debug("Bad pipe, Waiting for connect"); DisconnectNamedPipe(fifohandle); ConnectNamedPipe(fifohandle,&ov1); WaitForSingleObjectEx(fifohandle,timer,TRUE); } debug2("peek %ld bytes, error %ld",ret, err); return ret; } void win32_fifo_close(void) { debug1("Attempting to close handle %p", fifohandle); if(fifohandle) { DisconnectNamedPipe(fifohandle); CloseHandle(fifohandle); } fifohandle = NULL; } int win32_fifo_mkfifo(const char *path) { HANDLE ret; win32_fifo_close(); #ifdef WANT_WIN32_UNICODE wchar_t *str; if(INT123_win32_utf8_wide(path,&str,NULL) == 0) { fprintf(stderr,"Cannot get FIFO name, likely out of memory\n"); return -1; } #if (DEBUG == 1) fwprintf(stderr,L"CreateNamedPipeW %ws\n", str); #endif ret = CreateNamedPipeW(str,PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,PIPE_TYPE_BYTE,1,255,255,0,NULL); free(str); #else #if (DEBUG == 1) fprintf(stderr,"CreateNamedPipeA %s\n", path); #endif ret = CreateNamedPipeA(path,PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,PIPE_TYPE_BYTE,1,255,255,0,NULL); #endif /* WANT_WIN32_UNICODE */ if(ret == INVALID_HANDLE_VALUE) return -1; fifohandle = ret; /* Wait for client */ ConnectNamedPipe(fifohandle,&ov1); WaitForSingleObjectEx(fifohandle,INFINITE,TRUE); return 0; } #endif /* WANT_WIN32_FIFO */