| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include <winpr/crt.h> |
| #include <winpr/heap.h> |
| #include <winpr/handle.h> |
| |
| #include <winpr/thread.h> |
| |
| #ifdef HAVE_UNISTD_H |
| #include <unistd.h> |
| #endif |
| |
| #include "../log.h" |
| #define TAG WINPR_TAG("thread") |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) |
| { |
| char* p; |
| size_t length; |
| char* pBeg; |
| char* pEnd; |
| char* buffer; |
| char* pOutput; |
| int numArgs = 0; |
| LPSTR* pArgs; |
| size_t maxNumArgs; |
| size_t maxBufferSize; |
| size_t cmdLineLength; |
| BOOL* lpEscapedChars; |
| LPSTR lpEscapedCmdLine; |
| |
| if (!lpCmdLine) |
| return NULL; |
| |
| if (!pNumArgs) |
| return NULL; |
| |
| pArgs = NULL; |
| lpEscapedCmdLine = NULL; |
| cmdLineLength = strlen(lpCmdLine); |
| lpEscapedChars = (BOOL*)calloc(cmdLineLength + 1, sizeof(BOOL)); |
| |
| if (!lpEscapedChars) |
| return NULL; |
| |
| if (strstr(lpCmdLine, "\\\"")) |
| { |
| size_t i; |
| size_t n; |
| char* pLastEnd = NULL; |
| lpEscapedCmdLine = (char*)calloc(cmdLineLength + 1, sizeof(char)); |
| |
| if (!lpEscapedCmdLine) |
| { |
| free(lpEscapedChars); |
| return NULL; |
| } |
| |
| p = (char*)lpCmdLine; |
| pLastEnd = (char*)lpCmdLine; |
| pOutput = (char*)lpEscapedCmdLine; |
| |
| while (p < &lpCmdLine[cmdLineLength]) |
| { |
| pBeg = strstr(p, "\\\""); |
| |
| if (!pBeg) |
| { |
| length = strlen(p); |
| CopyMemory(pOutput, p, length); |
| pOutput += length; |
| break; |
| } |
| |
| pEnd = pBeg + 2; |
| |
| while (pBeg >= lpCmdLine) |
| { |
| if (*pBeg != '\\') |
| { |
| pBeg++; |
| break; |
| } |
| |
| pBeg--; |
| } |
| |
| n = ((pEnd - pBeg) - 1); |
| length = (pBeg - pLastEnd); |
| CopyMemory(pOutput, p, length); |
| pOutput += length; |
| p += length; |
| |
| for (i = 0; i < (n / 2); i++) |
| *pOutput++ = '\\'; |
| |
| p += n + 1; |
| |
| if ((n % 2) != 0) |
| lpEscapedChars[pOutput - lpEscapedCmdLine] = TRUE; |
| |
| *pOutput++ = '"'; |
| pLastEnd = p; |
| } |
| |
| *pOutput++ = '\0'; |
| lpCmdLine = (LPCSTR)lpEscapedCmdLine; |
| cmdLineLength = strlen(lpCmdLine); |
| } |
| |
| maxNumArgs = 2; |
| p = (char*)lpCmdLine; |
| |
| while (p < lpCmdLine + cmdLineLength) |
| { |
| p += strcspn(p, " \t"); |
| p += strspn(p, " \t"); |
| maxNumArgs++; |
| } |
| |
| maxBufferSize = (maxNumArgs * (sizeof(char*))) + (cmdLineLength + 1); |
| buffer = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, maxBufferSize); |
| |
| if (!buffer) |
| { |
| free(lpEscapedCmdLine); |
| free(lpEscapedChars); |
| return NULL; |
| } |
| |
| pArgs = (LPSTR*)buffer; |
| pOutput = (char*)&buffer[maxNumArgs * (sizeof(char*))]; |
| p = (char*)lpCmdLine; |
| |
| while (p < lpCmdLine + cmdLineLength) |
| { |
| pBeg = p; |
| |
| while (1) |
| { |
| p += strcspn(p, " \t\"\0"); |
| |
| if ((*p != '"') || !lpEscapedChars[p - lpCmdLine]) |
| break; |
| |
| p++; |
| } |
| |
| if (*p != '"') |
| { |
| |
| length = (p - pBeg); |
| CopyMemory(pOutput, pBeg, length); |
| pOutput[length] = '\0'; |
| pArgs[numArgs++] = pOutput; |
| pOutput += (length + 1); |
| } |
| else |
| { |
| p++; |
| |
| while (1) |
| { |
| p += strcspn(p, "\"\0"); |
| |
| if ((*p != '"') || !lpEscapedChars[p - lpCmdLine]) |
| break; |
| |
| p++; |
| } |
| |
| if (*p != '"') |
| WLog_ERR(TAG, "parsing error: uneven number of unescaped double quotes!"); |
| |
| if (*p && *(++p)) |
| p += strcspn(p, " \t\0"); |
| |
| pArgs[numArgs++] = pOutput; |
| |
| while (pBeg < p) |
| { |
| if (*pBeg != '"') |
| *pOutput++ = *pBeg; |
| |
| pBeg++; |
| } |
| |
| *pOutput++ = '\0'; |
| } |
| |
| p += strspn(p, " \t"); |
| } |
| |
| free(lpEscapedCmdLine); |
| free(lpEscapedChars); |
| *pNumArgs = numArgs; |
| return pArgs; |
| } |
| |
| #ifndef _WIN32 |
| |
| LPWSTR* CommandLineToArgvW(LPCWSTR lpCmdLine, int* pNumArgs) |
| { |
| return NULL; |
| } |
| |
| #endif |