Пример #1
0
nh_bool get_gamedir(enum game_dirs dirtype, wchar_t *buf)
{
    wchar_t *subdir;
    wchar_t appPath[MAX_PATH], nhPath[MAX_PATH];

    /* Get the location of "AppData\Roaming" (Vista, 7) or "Application Data" (XP).
     * The returned Path does not include a trailing backslash. */
    if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, appPath)))
        return FALSE;

    switch (dirtype) {
    case CONFIG_DIR:
        subdir = L"\\";
        break;
    case SAVE_DIR:
        subdir = L"\\save\\";
        break;
    case LOG_DIR:
        subdir = L"\\log\\";
        break;
    }

    snwprintf(nhPath, MAX_PATH, L"%s\\NitroHack", appPath);
    _wmkdir(nhPath);

    snwprintf(buf, BUFSZ, L"%s%s", nhPath, subdir);
    _wmkdir(buf);

    return TRUE;
}
Пример #2
0
VOID UpdateGui(HWND hwnd, DWORD nConverted, DWORD nTotal, LPCWSTR lpLastConverted)
{
    WCHAR szwTitle[256];
    WCHAR szwProgress[256];
    DWORD dwPercent = 0;

    dwPercent = (unsigned int)(((float)nConverted / (float)nTotal) * (float)100);

    snwprintf(szwTitle, sizeof(szwTitle) / sizeof(WCHAR)-1, TITLE_CONVERTING, dwPercent);
    snwprintf(szwProgress, sizeof(szwTitle) / sizeof(WCHAR)-1, MSG_CONVERTED, nConverted, nTotal);

    dialog_update_progress(hwnd, dwPercent, szwTitle, szwProgress, lpLastConverted);
}
Пример #3
0
INT_PTR CALLBACK RangDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	wchar_t tmpstr[MAXSETTINGSSTRLEN+100];
	int i;

	switch (uMsg) {
		case WM_INITDIALOG:
			for (i=0;i<scores.n;++i) {
				snwprintf(tmpstr, MAXSETTINGSSTRLEN+100, L"%4d %s", scores.imena[i].bodova, scores.imena[i].ime);
				SendDlgItemMessage(hWnd, IDC_RANGLIST, LB_ADDSTRING, 0, (LPARAM)tmpstr);
			}
			break;

		case WM_COMMAND:
			switch (LOWORD(wParam)) {
				case IDCANCEL:
				case IDOK:
					EndDialog(hWnd, 0);
					break;
				case IDC_CLEARRANG:
					if (ClearRang(hWnd)) {
						SendDlgItemMessage(hWnd, IDC_RANGLIST, LB_RESETCONTENT, 0, 0);
					}
					break;
			}
			break;
		case WM_CLOSE:
			EndDialog(hWnd, 0);
			break;

		default:
			return FALSE;
	}

	return TRUE;
}
Пример #4
0
void LogWriter::log(WCHAR *fmt, va_list args)
{
	wstr_t logMessage = CLOCK.nowTimeWithMilliSec();
	size_t threadId = GET_CURRENT_THREAD_ID();

	logMessage += L"\t";

	Thread *thread = ThreadManager::getInstance().at(threadId);
	if (thread) {
		logMessage += thread->name();
	}
	else {
		logMessage += prefix_;
	}
	array<WCHAR, SIZE_8 * 2> threadIdStr;
	snwprintf(threadIdStr, L"0x%X", threadId);

	logMessage += L":";
	logMessage += threadIdStr.data();
	logMessage += L"\t";

	array<WCHAR, SIZE_1024> logStr;

	vswprintf_s(logStr.data(), logStr.size(), fmt, args);

	logMessage += logStr.data();
	logMessage += L"\n";
	base_->log((WCHAR *)logMessage.c_str());
}
Пример #5
0
BOOL WritePrivateProfileIntW(LPCWSTR lpAppName, LPCWSTR lpKeyName, int val, LPCWSTR lpFileName)
{
    wchar_t buf[12];
    snwprintf(buf, 12, L"%d", val);

    return WritePrivateProfileStringW(lpAppName, lpKeyName, buf, lpFileName);
}
Пример #6
0
void cpix_Error_report(cpix_Error    * thisError,
                       wchar_t       * target,
                       size_t          targetLength)
{

    if (thisError != NULL)
        {
            const wchar_t
                * errorTypeName = GetErrorTypeName(thisError->type_);
            const wchar_t
                * detail = thisError->msg_;

            if (detail == NULL)
                {
                    detail = L"No details";
                }

            snwprintf(target,
                      targetLength,
                      L"Error type: %S. %S\n",
                      errorTypeName,
                      detail);
        }
    else
        {
            *target = 0;
        }
}
Пример #7
0
static const char *initerr(const char *message, const WCHAR *label, DWORD value)
{
    WCHAR *sysmsg;
    BOOL hassysmsg;
    WCHAR *beforele;
    WCHAR *afterle;
    int n;
    WCHAR *wmessage;
    WCHAR *wstr;
    const char *str;

    if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, value, 0, (LPWSTR) (&sysmsg), 0, NULL) != 0) {
        hassysmsg = TRUE;
        beforele = L" (";
        afterle = L")";
    } else {
        hassysmsg = FALSE;
        sysmsg = L"";
        beforele = L"";
        afterle = L"";
    }
    wmessage = toUTF16(message);
    n = _scwprintf(initErrorFormat, initErrorArgs);
    wstr = (WCHAR *) uiAlloc((n + 1) * sizeof (WCHAR), "WCHAR[]");
    snwprintf(wstr, n + 1, initErrorFormat, initErrorArgs);
    str = toUTF8(wstr);
    uiFree(wstr);
    if (hassysmsg)
        if (LocalFree(sysmsg) != NULL)
            logLastError("error freeing system message in loadLastError()");
    uiFree(wmessage);
    return str;
}
Пример #8
0
void rungame(void)
{
    int ret, role = initrole, race = initrace, gend = initgend, align = initalign;
    int fd = -1;
    char plname[BUFSZ];
    fnchar filename[1024];
    fnchar savedir[BUFSZ];
    long t;

    if (!get_gamedir(SAVE_DIR, savedir)) {
        curses_raw_print("Could not find where to put the logfile for a new game.");
        return;
    }

    if (!player_selection(&role, &race, &gend, &align, random_player))
        return;

    strncpy(plname, settings.plname, PL_NSIZ);
    /* The player name is set to "wizard" (again) in nh_start_game, so setting
     * it here just prevents wizmode player from being asked for a name. */
    if (ui_flags.playmode == MODE_WIZARD)
        strcpy(plname, "wizard");

    while (!plname[0])
        curses_getline("what is your name?", plname);
    if (plname[0] == '\033') /* canceled */
        return;

    t = (long)time(NULL);
#if defined(WIN32)
    snwprintf(filename, 1024, L"%ls%ld_%hs.nhgame", savedir, t, plname);
#else
    snprintf(filename, 1024, "%s%ld_%s.nhgame", savedir, t, plname);
#endif
    fd = sys_open(filename, O_TRUNC | O_CREAT | O_RDWR, FILE_OPEN_MASK);
    if (fd == -1) {
        curses_raw_print("Could not create the logfile.");
        return;
    }

    create_game_windows();
    if (!nh_start_game(fd, plname, role, race, gend, align, ui_flags.playmode)) {
        destroy_game_windows();
        close(fd);
        return;
    }

    load_keymap(); /* need to load the keymap after the game has been started */
    ret = commandloop();
    free_keymap();
    close(fd);

    destroy_game_windows();
    cleanup_messages();
    game_ended(ret, filename);
}
Пример #9
0
int WINAPI
wWinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
         LPWSTR  lpszCmdLine, int  nCmdShow)
{
    /* support for auto answering based on words in the assertion.
     * the assertion message is sent as a series of arguements (words) to the commandline.
     * set a "word" to 0xffffffff to let the word not affect this code.
     * set a "word" to 0xfffffffe to show the dialog.
     * set a "word" to 0x5 to ignore (program should continue).
     * set a "word" to 0x4 to retry (should fall into debugger).
     * set a "word" to 0x3 to abort (die).
     */
    DWORD regType;
    DWORD regValue = -1;
    DWORD regLength = sizeof regValue;
    HKEY hkeyCU, hkeyLM;
    RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\mozilla.org\\windbgdlg", 0, KEY_READ, &hkeyCU);
    RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\mozilla.org\\windbgdlg", 0, KEY_READ, &hkeyLM);
    int argc =0;
    for (int i = __argc - 1; regValue == (DWORD)-1 && i; --i) {
        bool ok = false;
        if (hkeyCU)
            ok = RegQueryValueExW(hkeyCU, __wargv[i], 0, &regType, (LPBYTE)&regValue, &regLength) == ERROR_SUCCESS;
        if (!ok && hkeyLM)
            ok = RegQueryValueExW(hkeyLM, __wargv[i], 0, &regType, (LPBYTE)&regValue, &regLength) == ERROR_SUCCESS;
        if (!ok)
            regValue = -1;
    }
    if (hkeyCU)
        RegCloseKey(hkeyCU);
    if (hkeyLM)
        RegCloseKey(hkeyLM);
    if (regValue != (DWORD)-1 && regValue != (DWORD)-2)
        return regValue;
    static const int size = 4096;
    static WCHAR msg[size];

#ifdef _MSC_VER
    StringCchPrintfW(msg,
#else
    snwprintf(msg,
#endif
              size,
              L"%s\n\nClick Abort to exit the Application.\n"
              L"Click Retry to Debug the Application.\n"
              L"Click Ignore to continue running the Application.",
              lpszCmdLine);
    msg[size - 1] = L'\0';
    return MessageBoxW(nullptr, msg, L"NSGlue_Assertion",
                       MB_ICONSTOP | MB_SYSTEMMODAL |
                       MB_ABORTRETRYIGNORE | MB_DEFBUTTON3);
}
int broker_os_add_qpid_route_link(const char *local, const char *remote)
{
    wchar_t cmd[1024];

    snwprintf(cmd, sizeof(cmd) / sizeof(*cmd), 
              L"%ls link add %s untrusted/untrusted@%s PLAIN", QPID_ROUTE,
              local, remote);

    if (start_process(QPID_ROUTE, cmd)) {
        return -1;
    }

    return 0;
}
Пример #11
0
string ChatCtrl::escapeUnicode(tstring str) {
	TCHAR buf[8];
	memzero(buf, sizeof(buf));

	int dist = 0;
	tstring::iterator i;
	while((i = std::find_if(str.begin() + dist, str.end(), std::bind2nd(std::greater<TCHAR>(), 0x7f))) != str.end()) {
		dist = (i+1) - str.begin(); // Random Acess iterators FTW
		snwprintf(buf, sizeof(buf), _T("%hd"), int(*i));
		str.replace(i, i+1, _T("\\ud\\u") + tstring(buf) + _T("?"));
		memzero(buf, sizeof(buf));
	}
	return Text::fromT(str);
}
int broker_os_add_qpid_route(const struct mh_qpid_route *route)
{
    wchar_t cmd[1024];

    if (route->aggregate && route->srclocal) {
        snwprintf(cmd, sizeof(cmd) / sizeof(*cmd), 
                  L"%ls --src-local route add %s %s %s %s", QPID_ROUTE,
                  route->dest, route->src, route->exchange, route->route_key);
    } else if (route->aggregate) {
        snwprintf(cmd, sizeof(cmd) / sizeof(*cmd),
                  L"%ls route add %s %s %s %s", QPID_ROUTE,
                  route->dest, route->src, route->exchange, route->route_key);
    } else {
        snwprintf(cmd, sizeof(cmd) / sizeof(*cmd),
                  L"%ls --timeout=5 dynamic add %s %s %s", QPID_ROUTE,
                  route->dest, route->src, route->exchange);
    }
 
    if (start_process(QPID_ROUTE, cmd)) {
        return -1;
    }

    return 0;
}
Пример #13
0
void print(const wchar_t* format, ...) {
  wchar_t buffer[1024];
  va_list vl;
  static std::size_t line = 0;
  line++;

  snwprintf(buffer, 5, L"%03d:", line);

  va_start(vl, format);
  vsnwprintf(buffer + 5, 1023 - 5, format, vl);
  va_end(vl);

  buffer[4] = L' ';
  buffer[1023] = L'\0';

  OutputDebugStringW(buffer);
}
Пример #14
0
HANDLE capture_mutex(char *name)
{
  wchar_t namew[MAX_PATH];
  snwprintf(namew,MAX_PATH,L"%S",name);
  UNICODE_STRING uniname;
  RtlInitUnicodeString(&uniname,namew);

  OBJECT_ATTRIBUTES oa;
  InitializeObjectAttributes(&oa,&uniname,OBJ_CASE_INSENSITIVE | OBJ_OPENIF,0,NULL);
  HANDLE mutex;
  DWORD access=MUTANT_ALL_ACCESS;
  NTSTATUS status=ZwOpenMutant(&mutex,access,&oa);
  if (!NT_SUCCESS(status)) return 0;
  printf("Mutex opened.\n");
  if (WaitForSingleObject(mutex,5000)==WAIT_OBJECT_0) return mutex;
  ZwClose(mutex);
  return NULL;
}
int broker_os_start_broker(char * const args[])
{
    int ret;
    wchar_t cmdline[CMD_LINE_LENGTH];
    int i = 0;
    const char *arg;

    for (arg = *args; arg; arg++) {
        int c = snwprintf(cmdline + i, CMD_LINE_LENGTH - i, L"%s ", arg);
        if (c < 0 || (i += c) >= (CMD_LINE_LENGTH - 1)) {
            return -1;
        }
    }

    ret = start_process(QPID_BROKER, cmdline);

    broker_federation_configure();

    return ret ? -1 : 0;
}
Пример #16
0
/*
 * Check workdir\fname is inside config_dir
 * The logic here is simple: we may reject some valid paths if ..\ is in any of the strings
 */
static BOOL
CheckConfigPath(const WCHAR *workdir, const WCHAR *fname, const settings_t *s)
{
    WCHAR tmp[MAX_PATH];
    const WCHAR *config_file = NULL;
    const WCHAR *config_dir = NULL;

    /* convert fname to full path */
    if (PathIsRelativeW(fname) )
    {
        snwprintf(tmp, _countof(tmp), L"%s\\%s", workdir, fname);
        tmp[_countof(tmp)-1] = L'\0';
        config_file = tmp;
    }
    else
    {
        config_file = fname;
    }

#ifdef UNICODE
    config_dir = s->config_dir;
#else
    if (MultiByteToWideChar(CP_UTF8, 0, s->config_dir, -1, widepath, MAX_PATH) == 0)
    {
        MsgToEventLog(M_SYSERR, TEXT("Failed to convert config_dir name to WideChar"));
        return FALSE;
    }
    config_dir = widepath;
#endif

    if (wcsncmp(config_dir, config_file, wcslen(config_dir)) == 0
        && wcsstr(config_file + wcslen(config_dir), L"..") == NULL)
    {
        return TRUE;
    }

    return FALSE;
}
Пример #17
0
int convert_to_roe(const wchar_t *src_path, const wchar_t *filename, const wchar_t *dest_path, convert_cb_t cb, void *cb_data)
{
    h3mlib_ctx_t h3m = NULL;
    wchar_t fullpath[MAX_PATH] = { 0 };
    wchar_t fullpath_out[MAX_PATH] = { 0 };
    wchar_t fullpath_patch[MAX_PATH] = { 0 };
    wchar_t *version = L"unknown";
    enum H3M_FORMAT fm_src = 0;
    int ret = 0;

    snwprintf(fullpath, sizeof(fullpath) / sizeof(fullpath[0])-1, L"%s\\%s", src_path, filename);

    h3m_read_convert_u(&h3m, fullpath, H3M_FORMAT_ROE, &fm_src, NULL, NULL, NULL, NULL);

    if (NULL == h3m)
    {
        if (NULL != cb)
        {
            if (0 != (ret = cb(filename, fm_src, (H3M_FORMAT_ROE != fm_src) ? CONVERT_RESULT_FAIL : CONVERT_RESULT_SKIP, cb_data)))
            {
                return ret;
            }
        }

        return 0;
    }

    switch (fm_src)
    {
    case H3M_FORMAT_AB:
        version = L"AB";
        break;
    case H3M_FORMAT_SOD:
        version = L"SoD";
        break;
    case H3M_FORMAT_WOG:
        version = L"WoG";
        break;
    default:
        version = L"??";
    }

    snwprintf(fullpath_out, sizeof(fullpath_out) / sizeof(fullpath_out[0])-1, L"%s\\[%s-RoE] %s", dest_path, version, filename);

    snwprintf(fullpath_patch, sizeof(fullpath_patch)-sizeof(fullpath_patch[0]) - 1, L"h3mpatches\\patch_%s", filename);

    if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(fullpath_patch))
    {
        h3m_object_patch_u(h3m, fullpath_patch);
    }

    h3m_write_u(h3m, fullpath_out);
    //h3m_compress(fullpath_out, fullpath_out);

    h3m_exit(&h3m);

    if (NULL != cb)
    {
        if (0 != (ret = cb(filename, fm_src, CONVERT_RESULT_SUCCESS, cb_data)))
        {
            return ret;
        }
    }

    return 0;
}
Пример #18
0
/* FIXME - like inject_into_thread we assume esp, but we could allocate our
 * own stack in the child and swap to that for transparency. */
bool
inject_into_new_process(HANDLE phandle, char *dynamo_path, bool map,
                        uint inject_location, void *inject_address)
{
    void *hook_target = NULL, *hook_location = NULL;
    uint old_prot; 
    size_t num_bytes_out;
    byte hook_buf[5];

    /* Possible child hook points */
    GET_NTDLL(KiUserApcDispatcher, (IN PVOID Unknown1, 
                                    IN PVOID Unknown2, 
                                    IN PVOID Unknown3, 
                                    IN PVOID ContextStart, 
                                    IN PVOID ContextBody));
    GET_NTDLL(KiUserExceptionDispatcher, (IN PVOID Unknown1, 
                                          IN PVOID Unknown2));

    /* Only ones that work, though I have hopes for KiUserException if can
     * find a better spot to trigger the exception, or we should implement
     * KiUserApc map requirement. */
    ASSERT_NOT_IMPLEMENTED(INJECT_LOCATION_IS_LDR(inject_location));
    switch(inject_location) {
    case INJECT_LOCATION_LdrLoadDll:
    case INJECT_LOCATION_LdrpLoadDll:
    case INJECT_LOCATION_LdrCustom:
    case INJECT_LOCATION_LdrpLoadImportModule:
    case INJECT_LOCATION_LdrDefault:
        /* caller provides the ldr address to use */
        ASSERT(inject_address != NULL);
        hook_location = inject_address;
        if (hook_location == NULL) {
            goto error;
        }
        break;
    case INJECT_LOCATION_KiUserApc:
        hook_location = (void *)KiUserApcDispatcher;
        ASSERT(map);
        break;
    case INJECT_LOCATION_KiUserException:
        hook_location = (void *)KiUserExceptionDispatcher;
        break;
    default:
        ASSERT_NOT_REACHED();
        goto error;
    }

    /* read in code at hook */
    if (!nt_read_virtual_memory(phandle, hook_location, hook_buf,
                                sizeof(hook_buf), &num_bytes_out) ||
        num_bytes_out != sizeof(hook_buf)) {
        goto error;
    }

    if (map) {
        hook_target = NULL; /* for compiler */
        /* NYI see case 102, plan is to remote map in our dll, link and rebase if
         * necessary and hook to a routine in our dll */
        ASSERT_NOT_IMPLEMENTED(false);
    } else {
        byte *remote_code_buffer = NULL, *remote_data_buffer;
        /* max usage for local_buf is for writing the dr library name
         * 2*MAX_PATH (unicode) + sizoef(UNICODE_STRING) + 2, round up to
         * 3*MAX_PATH to be safe */
        byte local_buf[3*MAX_PATH];
        byte *cur_local_pos, *cur_remote_pos, *jmp_fixup1, *jmp_fixup2;
        char *takeover_func = "dynamorio_app_init_and_early_takeover";
        PUNICODE_STRING mod, mod_remote;
        PANSI_STRING func, func_remote;
        int res;
        size_t num_bytes_in;

        GET_NTDLL(LdrLoadDll, (IN PCWSTR PathToFile OPTIONAL,
                               IN PULONG Flags OPTIONAL,
                               IN PUNICODE_STRING ModuleFileName,
                               OUT PHANDLE ModuleHandle));
        GET_NTDLL(LdrGetProcedureAddress, (IN HANDLE ModuleHandle,
                                           IN PANSI_STRING ProcedureName OPTIONAL,
                                           IN ULONG Ordinal OPTIONAL,
                                           OUT FARPROC *ProcedureAddress));
#define GET_PROC_ADDR_BAD_ADDR 0xffbadd11
        GET_NTDLL(NtProtectVirtualMemory, (IN HANDLE ProcessHandle,
                                           IN OUT PVOID *BaseAddress,
                                           IN OUT PULONG ProtectSize,
                                           IN ULONG NewProtect,
                                           OUT PULONG OldProtect));
        GET_NTDLL(NtContinue, (IN PCONTEXT Context,
                               IN BOOLEAN TestAlert));

        /* get buffer for emitted code and data */
        if (!NT_SUCCESS(nt_remote_allocate_virtual_memory(phandle, &remote_code_buffer,
                                                          2*PAGE_SIZE, PAGE_READWRITE,
                                                          MEM_COMMIT))) {
            goto error;
        }
        remote_data_buffer = remote_code_buffer + PAGE_SIZE;
        
        /* write data */
        /* FIXME the two writes are similar (unicode vs ascii), could combine */
        /* First UNICODE_STRING to library */
        cur_remote_pos = remote_data_buffer;
        cur_local_pos = local_buf;
        ASSERT_ROOM(cur_local_pos, local_buf, sizeof(UNICODE_STRING));
        mod = (PUNICODE_STRING)cur_local_pos;
        memset(mod, 0, sizeof(UNICODE_STRING));
        cur_local_pos += sizeof(UNICODE_STRING);
        mod->Buffer = (wchar_t *)(cur_remote_pos + (cur_local_pos - local_buf));
        ASSERT_ROOM(cur_local_pos, local_buf, 2*MAX_PATH+2 /* plus null */);
        res = snwprintf((wchar_t *)cur_local_pos, 2*MAX_PATH, L"%hs", dynamo_path);
        ASSERT(res > 0);
        if (res > 0) {
            cur_local_pos += (2*res);
            ASSERT_TRUNCATE(mod->Length, ushort, 2*res);
            mod->Length = (ushort)(2*res);
            mod->MaximumLength = (ushort)(2*res);
        }
        /* ensure NULL termination, just in case */
        *(wchar_t *)cur_local_pos = L'\0';
        cur_local_pos += sizeof(wchar_t);
        /* write to remote process */
        num_bytes_in = cur_local_pos - local_buf;
        if (!nt_write_virtual_memory(phandle, cur_remote_pos, local_buf,
                                     num_bytes_in, &num_bytes_out) ||
            num_bytes_out != num_bytes_in) {
            goto error;
        }
        mod_remote = (PUNICODE_STRING)cur_remote_pos;
        cur_remote_pos += num_bytes_out;

        /* now write init/takeover func */
        cur_local_pos = local_buf;
        ASSERT_ROOM(cur_local_pos, local_buf, sizeof(ANSI_STRING));
        func = (PANSI_STRING)cur_local_pos;
        memset(func, 0, sizeof(ANSI_STRING));
        cur_local_pos += sizeof(ANSI_STRING);
        func->Buffer = (PCHAR) cur_remote_pos + (cur_local_pos - local_buf);
        ASSERT_ROOM(cur_local_pos, local_buf, strlen(takeover_func)+1);
        strncpy((char *)cur_local_pos, takeover_func, strlen(takeover_func));
        cur_local_pos += strlen(takeover_func);
        ASSERT_TRUNCATE(func->Length, ushort, strlen(takeover_func));
        func->Length = (ushort)strlen(takeover_func);
        func->MaximumLength = (ushort)strlen(takeover_func);
        *cur_local_pos++ = '\0'; /* ensure NULL termination, just in case */
        /* write to remote_process */
        num_bytes_in = cur_local_pos - local_buf;
        if (!nt_write_virtual_memory(phandle, cur_remote_pos, local_buf,
                                     num_bytes_in, &num_bytes_out) ||
            num_bytes_out != num_bytes_in) {
            goto error;
        }
        func_remote = (PANSI_STRING)cur_remote_pos;
        cur_remote_pos += num_bytes_out;
        
        /* now make data page read only */
        res = nt_remote_protect_virtual_memory(phandle, remote_data_buffer, 
                                               PAGE_SIZE, PAGE_READONLY,
                                               &old_prot);
        ASSERT(res);
        
#define INSERT_INT(value)         \
  *(int *)cur_local_pos = value;  \
  cur_local_pos += sizeof(int)

#define PUSH_IMMEDIATE(value)     \
  *cur_local_pos++ = PUSH_IMM32;  \
  INSERT_INT(value)

#define PUSH_SHORT_IMMEDIATE(value)     \
  *cur_local_pos++ = PUSH_IMM8;         \
  *cur_local_pos++ = value

#define MOV_ESP_TO_EAX()                \
  *cur_local_pos++ = MOV_RM32_2_REG32;  \
  *cur_local_pos++ = MOV_ESP_2_EAX_RM

/* FIXME - all values are small use imm8 version */
#define ADD_TO_EAX(value)               \
  *cur_local_pos++ = ADD_EAX_IMM32;     \
  INSERT_INT(value)

#define INSERT_REL32_ADDRESS(target)    \
  IF_X64(ASSERT_NOT_IMPLEMENTED(false)); \
  INSERT_INT((int)(ptr_int_t)((byte *)target - \
                              (((cur_local_pos - local_buf)+4)+cur_remote_pos)))

#define CALL(target_func)               \
  *cur_local_pos++ = CALL_REL32;        \
  INSERT_REL32_ADDRESS(target_func)

/* ecx will hold OldProtection afterwards */
#define PROT_IN_ECX 0xbad15bad /* doesn't match a PAGE_* define */
#define CHANGE_PROTECTION(start, size, new_protection)                \
  *cur_local_pos++ = PUSH_EAX; /* OldProtect slot */                  \
  MOV_ESP_TO_EAX(); /* get &OldProtect */                             \
  IF_X64(ASSERT_NOT_IMPLEMENTED(false));                              \
  PUSH_IMMEDIATE((int)(ALIGN_FORWARD(start+size, PAGE_SIZE) -         \
                 ALIGN_BACKWARD(start, PAGE_SIZE))); /* ProtectSize */ \
  PUSH_IMMEDIATE((int)ALIGN_BACKWARD(start, PAGE_SIZE)); /* BaseAddress */ \
  *cur_local_pos++ = PUSH_EAX; /* arg 5 &OldProtect */                \
  if (new_protection == PROT_IN_ECX) {                                \
      *cur_local_pos++ = PUSH_ECX; /* arg 4 NewProtect */             \
  } else {                                                            \
      PUSH_IMMEDIATE(new_protection); /* arg 4 NewProtect */          \
  }                                                                   \
  ADD_TO_EAX(-4); /* get &ProtectSize */                              \
  *cur_local_pos++ = PUSH_EAX; /* arg 3 &ProtectSize */               \
  ADD_TO_EAX(-4); /* get &BaseAddress */                              \
  *cur_local_pos++ = PUSH_EAX; /* arg 2 &BaseAddress */               \
  PUSH_IMMEDIATE((int)(ptr_int_t)NT_CURRENT_PROCESS); /* arg ProcessHandle */ \
  CALL(NtProtectVirtualMemory);                                       \
  /* no error checking, can't really do anything about it, FIXME */   \
  /* stdcall so just the three slots we made for the ptr arguments    \
   * left on the stack */                                             \
  *cur_local_pos++ = POP_ECX; /* pop BaseAddress */                   \
  *cur_local_pos++ = POP_ECX; /* pop ProtectSize */                   \
  *cur_local_pos++ = POP_ECX /* pop OldProtect into ecx */


        /* write code */
        /* xref case 3821, first call to a possibly hooked routine should be
         * more then 5 bytes into the page, which is satisfied (though is not
         * clear if any hookers would manage to get in first). */
        cur_remote_pos = remote_code_buffer;
        cur_local_pos = local_buf;
        hook_target = cur_remote_pos;
        /* for inject_location INJECT_LOCATION_Ldr* we stick the address used
         * at the start of the code for the child's use */
        if (INJECT_LOCATION_IS_LDR(inject_location)) {
            IF_X64(ASSERT_NOT_IMPLEMENTED(false));
            INSERT_INT((int)(ptr_int_t)inject_address);
            hook_target = cur_remote_pos + 4;  /* skip the address */
        }

#if DEBUG_LOOP
        *cur_local_pos++ = JMP_REL8;
        *cur_local_pos++ = 0xfe;
#endif

        /* save current state */
        *cur_local_pos++ = PUSHA;
        *cur_local_pos++ = PUSHF;

        /* restore trampoline, first make writable */
        CHANGE_PROTECTION(hook_location, 5, PAGE_EXECUTE_READWRITE);
        *cur_local_pos++ = MOV_IMM32_2_RM32; /* restore first 4 bytes of hook */
        *cur_local_pos++ = MOV_IMM_RM_ABS;
        IF_X64(ASSERT_NOT_IMPLEMENTED(false));
        INSERT_INT((int)(ptr_int_t)hook_location);
        INSERT_INT(*(int *)hook_buf);
        *cur_local_pos++ = MOV_IMM8_2_RM8; /* restore 5th byte of the hook */
        *cur_local_pos++ = MOV_IMM_RM_ABS;
        IF_X64(ASSERT_NOT_IMPLEMENTED(false));
        INSERT_INT((int)(ptr_int_t)hook_location+4);
        *cur_local_pos++ = hook_buf[4];
        /* hook restored, restore protection */
        CHANGE_PROTECTION(hook_location, 5, PROT_IN_ECX);

        if (inject_location == INJECT_LOCATION_KiUserException) {
            /* Making the first page of the image unreadable triggers an exception
             * to early to use the loader, might try pointing the import table ptr
             * to bad memory instead TOTRY, whatever we do should fixup here */
            ASSERT_NOT_IMPLEMENTED(false);
        }
        
        /* call LdrLoadDll to load dr library */
        *cur_local_pos++ = PUSH_EAX; /* need slot for OUT hmodule*/
        MOV_ESP_TO_EAX();
        *cur_local_pos++ = PUSH_EAX; /* arg 4 OUT *hmodule */
        IF_X64(ASSERT_NOT_IMPLEMENTED(false));
        PUSH_IMMEDIATE((int)(ptr_int_t)mod_remote); /* our library name */
        PUSH_SHORT_IMMEDIATE(0x0); /* Flags OPTIONAL */
        PUSH_SHORT_IMMEDIATE(0x0); /* PathToFile OPTIONAL */
        CALL(LdrLoadDll); /* see signature at decleration above */

        /* stdcall so removed args so top of stack is now the slot containing the
         * returned handle.  Use LdrGetProcedureAddress to get the address of the
         * dr init and takeover function. Is ok to call even if LdrLoadDll failed,
         * so we check for errors afterwards. */
        *cur_local_pos++ = POP_ECX; /* dr module handle */
        *cur_local_pos++ = PUSH_ECX; /* need slot for out ProcedureAddress */
        MOV_ESP_TO_EAX();
        *cur_local_pos++ = PUSH_EAX; /* arg 4 OUT *ProcedureAddress */
        PUSH_SHORT_IMMEDIATE(0x0); /* Ordinal OPTIONAL */
        IF_X64(ASSERT_NOT_IMPLEMENTED(false));
        PUSH_IMMEDIATE((int)(ptr_int_t)func_remote); /* func name */
        *cur_local_pos++ = PUSH_ECX; /* module handle */
        CALL(LdrGetProcedureAddress); /* see signature at decleration above */

        /* Top of stack is now the dr init and takeover function (stdcall removed
         * args). Check for errors and bail (FIXME debug build report somehow?) */
        *cur_local_pos++ = CMP_EAX_IMM32;
        INSERT_INT(STATUS_SUCCESS);
        *cur_local_pos++ = POP_EAX; /* dr init_and_takeover function */
        *cur_local_pos++ = JNZ_REL8; /* FIXME - should check >= 0 instead? */
        jmp_fixup1 = cur_local_pos++; /* jmp to after call below */
        /* Xref case 8373, LdrGetProcedureAdderss sometimes returns an
         * address of 0xffbadd11 even though it returned STATUS_SUCCESS */
        *cur_local_pos++ = CMP_EAX_IMM32;
        INSERT_INT(GET_PROC_ADDR_BAD_ADDR);
        *cur_local_pos++ = JZ_REL8; /* JZ == JE */
        jmp_fixup2 = cur_local_pos++; /* jmp to after call below */
        IF_X64(ASSERT_NOT_IMPLEMENTED(false));
        PUSH_IMMEDIATE((int)(ptr_int_t)remote_code_buffer); /* arg to takeover func */
        PUSH_IMMEDIATE(inject_location); /* arg to takeover func */
        *cur_local_pos++ = CALL_RM32; /* call EAX */
        *cur_local_pos++ = CALL_EAX_RM;
        *cur_local_pos++ = POP_ECX; /* cdecl so pop arg */
        *cur_local_pos++ = POP_ECX; /* cdecl so pop arg */
        /* Now patch the jnz above (if error) to go to here */
        ASSERT_TRUNCATE(*jmp_fixup1, byte, cur_local_pos - (jmp_fixup1+1));
        *jmp_fixup1 = (byte)(cur_local_pos - (jmp_fixup1+1)); /* target of jnz */
        ASSERT_TRUNCATE(*jmp_fixup2, byte, cur_local_pos - (jmp_fixup2+1));
        *jmp_fixup2 = (byte)(cur_local_pos - (jmp_fixup2+1)); /* target of jz */
        *cur_local_pos++ = POPF;
        *cur_local_pos++ = POPA;
        if (inject_location != INJECT_LOCATION_KiUserException) {
            /* jmp back to the hook location to resume execution */
            *cur_local_pos++ = JMP_REL32;
            INSERT_REL32_ADDRESS(hook_location);
        } else {
            /* we triggered the exception, so do an NtContinue back */
            /* see callback.c, esp+4 holds CONTEXT ** */
            *cur_local_pos++ = POP_EAX;  /* EXCEPTION_RECORD ** */
            *cur_local_pos++ = POP_EAX;  /* CONTEXT ** */
            PUSH_SHORT_IMMEDIATE(FALSE); /* arg 2 TestAlert */
            *cur_local_pos++ = MOV_RM32_2_REG32;
            *cur_local_pos++ = MOV_derefEAX_2_EAX_RM; /* CONTEXT * -> EAX */
            *cur_local_pos++ = PUSH_EAX; /* push CONTEXT * (arg 1) */
            CALL(NtContinue);
            /* should never get here, will be zeroed memory so will crash if
             * we do happen to get here, good enough reporting */
        }

        /* Our emitted code above is much less then the sizeof local_buf,
         * but we'll add a check here (after the fact so not robust if really
         * overflowed) that we didn't even come close (someon adding large amounts
         * of code should hit this. FIXME - do better? */
        ASSERT_ROOM(cur_local_pos, local_buf, MAX_PATH);
        num_bytes_in = cur_local_pos - local_buf;
        if (!nt_write_virtual_memory(phandle, cur_remote_pos, local_buf,
                                     num_bytes_in, &num_bytes_out) ||
            num_bytes_out != num_bytes_in) {
            goto error;
        }
        cur_remote_pos += num_bytes_out;
        /* now make code page rx */
        res = nt_remote_protect_virtual_memory(phandle, remote_code_buffer, 
                                               PAGE_SIZE, PAGE_EXECUTE_READ,
                                               &old_prot);
        ASSERT(res);

#undef INSERT_INT
#undef PUSH_IMMEDIATE
#undef PUSH_SHORT_IMMEDIATE
#undef MOV_ESP_TO_EAX
#undef ADD_TO_EAX
#undef INSERT_REL32_ADDRESS
#undef CALL
#undef PROT_IN_ECX
#undef CHANGE_PROTECTION
    }

    /* place hook */
    ASSERT(sizeof(hook_buf) == 5); /* standard 5 byte jmp rel32 hook */
    hook_buf[0] = JMP_REL32;
    IF_X64(ASSERT_NOT_IMPLEMENTED(false));
    *(int *)(&hook_buf[1]) = (int)((byte *)hook_target - ((byte *)hook_location + 5));
    if (!nt_remote_protect_virtual_memory(phandle, hook_location,
                                          sizeof(hook_buf),
                                          PAGE_EXECUTE_READWRITE, &old_prot)) {
        goto error;
    }
    if (!nt_write_virtual_memory(phandle, hook_location, hook_buf,
                                 sizeof(hook_buf), &num_bytes_out) ||
        num_bytes_out != sizeof(hook_buf)) {
        goto error;
    }
    if (!nt_remote_protect_virtual_memory(phandle, hook_location,
                                          sizeof(hook_buf),
                                          old_prot, &old_prot)) {
        goto error;
    }

    return true;

    error:
    /* we do not recover any changes in the child's address space */
    return false;
}
Пример #19
0
int wmain(int argc, wchar_t **argv) {
   // having these declarations at the start of the function is only needed for C compatibility
   int i;
   int soutBufferSize;
   int nr;
   char **vlc_argv; 
   wchar_t *soutOption; 
   wchar_t *config; 
   wchar_t *path; 
   libvlc_instance_t *vlc;
   libvlc_media_t *media;
   libvlc_media_player_t *player;
   libvlc_event_manager_t *eventManager;

   // init arguments
   if(argc < 3) {
      fwprintf(stdout, ENDLN(L"Usage: vlcwrapper <input> <soutstring> [optional vlc arguments]"));
      return 1;
   }

	// print some information
	path = argv[1];
   config = argv[2];
   fwprintf(stdout, ENDLN(L"I VLCWrapper version %s, using VLC %hs"), VERSION, libvlc_get_version());
   fwprintf(stdout, ENDLN(L"A path %s"), path);
   fwprintf(stdout, ENDLN(L"A config %s"), config);
   
   // init state machine  
   global_state = STATE_NULL;

   // arguments (you shouldn't need these in normal usage; but we don't support all arguments by ourself yet)
   nr = argc - 3;
   vlc_argv = (char**)malloc(nr * sizeof(char*));
   for(i = 3; i < argc; i++) {
      fwprintf(stdout, ENDLN(L"A cmd %d %s"), i - 3, argv[i]);
	  vlc_argv[i - 3] = to_utf8(argv[i]);
   }

   // init vlc
   vlc = libvlc_new(nr, vlc_argv);
   libvlc_set_user_agent(vlc, to_utf8(USER_AGENT), to_utf8(HTTP_USER_AGENT));
   
   // create media and set sout string
   media = libvlc_media_new_path(vlc, to_utf8(path));
   soutBufferSize = wcslen(config) + 6;
   soutOption = (wchar_t*)malloc(soutBufferSize * sizeof(wchar_t));
   snwprintf(soutOption, soutBufferSize, soutBufferSize, L"sout=%s", config);
   libvlc_media_add_option(media, to_utf8(soutOption));
   
   // create player and listen for events
   player = libvlc_media_player_new_from_media(media);
   eventManager = libvlc_media_player_event_manager(player);
   register_event(eventManager, libvlc_MediaPlayerPlaying, STATE_PLAYING);
   register_event(eventManager, libvlc_MediaPlayerEncounteredError, STATE_ERROR);
   register_event(eventManager, libvlc_MediaPlayerEndReached, STATE_FINISHED);
   
   // start playing it
   libvlc_media_player_play(player);
   
   // wait till it's started or stopped because of an error
   while(global_state != STATE_ERROR && global_state != STATE_PLAYING)
      millisleep(100);

   // let it play till it has finished, while printing status information
   while(global_state == STATE_PLAYING) {
      fwprintf(stdout, ENDLN(L"P %d"), libvlc_media_player_get_time(player));
      fflush(stdout);
      millisleep(LOG_INTERVAL);
   }
   
   // stop playing
   libvlc_media_player_stop(player);
   
   // release objects in memory
   libvlc_media_release(media);
   libvlc_media_player_release(player);
   libvlc_release(vlc);
   return 0;
}
Пример #20
0
int launch_server(const std::string& socket_spec) {
#if defined(_WIN32)
    /* we need to start the server in the background                    */
    /* we create a PIPE that will be used to wait for the server's "OK" */
    /* message since the pipe handles must be inheritable, we use a     */
    /* security attribute                                               */
    SECURITY_ATTRIBUTES   sa;
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    // Redirect stdin to Windows /dev/null. If we instead pass an original
    // stdin/stdout/stderr handle and it is a console handle, when the adb
    // server starts up, the C Runtime will see a console handle for a process
    // that isn't connected to a console and it will configure
    // stdin/stdout/stderr to be closed. At that point, freopen() could be used
    // to reopen stderr/out, but it would take more massaging to fixup the file
    // descriptor number that freopen() uses. It's simplest to avoid all of this
    // complexity by just redirecting stdin to `nul' and then the C Runtime acts
    // as expected.
    unique_handle   nul_read(CreateFileW(L"nul", GENERIC_READ,
            FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL, NULL));
    if (nul_read.get() == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "Cannot open 'nul': %s\n",
                android::base::SystemErrorCodeToString(GetLastError()).c_str());
        return -1;
    }

    // Create pipes with non-inheritable read handle, inheritable write handle. We need to connect
    // the subprocess to pipes instead of just letting the subprocess inherit our existing
    // stdout/stderr handles because a DETACHED_PROCESS cannot write to a console that it is not
    // attached to.
    unique_handle   ack_read, ack_write;
    if (!_create_anonymous_pipe(&ack_read, &ack_write, &sa)) {
        return -1;
    }
    unique_handle   stdout_read, stdout_write;
    if (!_create_anonymous_pipe(&stdout_read, &stdout_write, &sa)) {
        return -1;
    }
    unique_handle   stderr_read, stderr_write;
    if (!_create_anonymous_pipe(&stderr_read, &stderr_write, &sa)) {
        return -1;
    }

    /* Some programs want to launch an adb command and collect its output by
     * calling CreateProcess with inheritable stdout/stderr handles, then
     * using read() to get its output. When this happens, the stdout/stderr
     * handles passed to the adb client process will also be inheritable.
     * When starting the adb server here, care must be taken to reset them
     * to non-inheritable.
     * Otherwise, something bad happens: even if the adb command completes,
     * the calling process is stuck while read()-ing from the stdout/stderr
     * descriptors, because they're connected to corresponding handles in the
     * adb server process (even if the latter never uses/writes to them).
     * Note that even if we don't pass these handles in the STARTUPINFO struct,
     * if they're marked inheritable, they're still inherited, requiring us to
     * deal with this.
     *
     * If we're still having problems with inheriting random handles in the
     * future, consider using PROC_THREAD_ATTRIBUTE_HANDLE_LIST to explicitly
     * specify which handles should be inherited: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx
     *
     * Older versions of Windows return console pseudo-handles that cannot be
     * made non-inheritable, so ignore those failures.
     */
    _try_make_handle_noninheritable(GetStdHandle(STD_INPUT_HANDLE));
    _try_make_handle_noninheritable(GetStdHandle(STD_OUTPUT_HANDLE));
    _try_make_handle_noninheritable(GetStdHandle(STD_ERROR_HANDLE));

    STARTUPINFOW    startup;
    ZeroMemory( &startup, sizeof(startup) );
    startup.cb = sizeof(startup);
    startup.hStdInput  = nul_read.get();
    startup.hStdOutput = stdout_write.get();
    startup.hStdError  = stderr_write.get();
    startup.dwFlags    = STARTF_USESTDHANDLES;

    // Verify that the pipe_write handle value can be passed on the command line
    // as %d and that the rest of adb code can pass it around in an int.
    const int ack_write_as_int = cast_handle_to_int(ack_write.get());
    if (cast_int_to_handle(ack_write_as_int) != ack_write.get()) {
        // If this fires, either handle values are larger than 32-bits or else
        // there is a bug in our casting.
        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx
        fprintf(stderr, "Cannot fit pipe handle value into 32-bits: 0x%p\n",
                ack_write.get());
        return -1;
    }

    // get path of current program
    WCHAR       program_path[MAX_PATH];
    const DWORD module_result = GetModuleFileNameW(NULL, program_path,
                                                   arraysize(program_path));
    if ((module_result >= arraysize(program_path)) || (module_result == 0)) {
        // String truncation or some other error.
        fprintf(stderr, "Cannot get executable path: %s\n",
                android::base::SystemErrorCodeToString(GetLastError()).c_str());
        return -1;
    }

    WCHAR   args[64];
    snwprintf(args, arraysize(args), L"adb -L %s fork-server server --reply-fd %d",
              socket_spec.c_str(), ack_write_as_int);

    PROCESS_INFORMATION   pinfo;
    ZeroMemory(&pinfo, sizeof(pinfo));

    if (!CreateProcessW(
            program_path,                              /* program path  */
            args,
                                    /* the fork-server argument will set the
                                       debug = 2 in the child           */
            NULL,                   /* process handle is not inheritable */
            NULL,                    /* thread handle is not inheritable */
            TRUE,                          /* yes, inherit some handles */
            DETACHED_PROCESS, /* the new process doesn't have a console */
            NULL,                     /* use parent's environment block */
            NULL,                    /* use parent's starting directory */
            &startup,                 /* startup info, i.e. std handles */
            &pinfo )) {
        fprintf(stderr, "Cannot create process: %s\n",
                android::base::SystemErrorCodeToString(GetLastError()).c_str());
        return -1;
    }

    unique_handle   process_handle(pinfo.hProcess);
    pinfo.hProcess = NULL;

    // Close handles that we no longer need to complete the rest.
    CloseHandle(pinfo.hThread);
    pinfo.hThread = NULL;

    nul_read.reset();
    ack_write.reset();
    stdout_write.reset();
    stderr_write.reset();

    // Start threads to read from subprocess stdout/stderr and write to ours to make subprocess
    // errors easier to diagnose. Note that the threads internally create inheritable handles, but
    // that is ok because we've already spawned the subprocess.

    // In the past, reading from a pipe before the child process's C Runtime
    // started up and called GetFileType() caused a hang: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx#10244216
    // This is reportedly fixed in Windows Vista: https://support.microsoft.com/en-us/kb/2009703
    // I was unable to reproduce the problem on Windows XP. It sounds like a
    // Windows Update may have fixed this: https://www.duckware.com/tech/peeknamedpipe.html
    unique_handle   stdout_thread(reinterpret_cast<HANDLE>(
            _beginthreadex(NULL, 0, _redirect_stdout_thread, stdout_read.get(),
                           0, NULL)));
    if (stdout_thread.get() == nullptr) {
        fprintf(stderr, "Cannot create thread: %s\n", strerror(errno));
        return -1;
    }
    stdout_read.release();  // Transfer ownership to new thread

    unique_handle   stderr_thread(reinterpret_cast<HANDLE>(
            _beginthreadex(NULL, 0, _redirect_stderr_thread, stderr_read.get(),
                           0, NULL)));
    if (stderr_thread.get() == nullptr) {
        fprintf(stderr, "Cannot create thread: %s\n", strerror(errno));
        return -1;
    }
    stderr_read.release();  // Transfer ownership to new thread

    bool    got_ack = false;

    // Wait for the "OK\n" message, for the pipe to be closed, or other error.
    {
        char    temp[3];
        DWORD   count = 0;

        if (ReadFile(ack_read.get(), temp, sizeof(temp), &count, NULL)) {
            const CHAR  expected[] = "OK\n";
            const DWORD expected_length = arraysize(expected) - 1;
            if (count == expected_length &&
                memcmp(temp, expected, expected_length) == 0) {
                got_ack = true;
            } else {
                fprintf(stderr, "ADB server didn't ACK\n");
            }
        } else {
            const DWORD err = GetLastError();
            // If the ACK was not written and the process exited, GetLastError()
            // is probably ERROR_BROKEN_PIPE, in which case that info is not
            // useful to the user.
            fprintf(stderr, "could not read ok from ADB Server%s\n",
                    err == ERROR_BROKEN_PIPE ? "" :
                    android::base::StringPrintf(": %s",
                            android::base::SystemErrorCodeToString(err).c_str()).c_str());
        }
    }

    // Always try to wait a bit for threads reading stdout/stderr to finish.
    // If the process started ok, it should close the pipes causing the threads
    // to finish. If the process had an error, it should exit, also causing
    // the pipes to be closed. In that case we want to read all of the output
    // and write it out so that the user can diagnose failures.
    const DWORD     thread_timeout_ms = 15 * 1000;
    const HANDLE    threads[] = { stdout_thread.get(), stderr_thread.get() };
    const DWORD     wait_result = WaitForMultipleObjects(arraysize(threads),
            threads, TRUE, thread_timeout_ms);
    if (wait_result == WAIT_TIMEOUT) {
        // Threads did not finish after waiting a little while. Perhaps the
        // server didn't close pipes, or it is hung.
        fprintf(stderr, "Timed-out waiting for threads to finish reading from "
                "ADB Server\n");
        // Process handles are signaled when the process exits, so if we wait
        // on the handle for 0 seconds and it returns 'timeout', that means that
        // the process is still running.
        if (WaitForSingleObject(process_handle.get(), 0) == WAIT_TIMEOUT) {
            // We could TerminateProcess(), but that seems somewhat presumptive.
            fprintf(stderr, "ADB Server is running: process id %lu\n",
                    pinfo.dwProcessId);
        }
        return -1;
    }

    if (wait_result != WAIT_OBJECT_0) {
        fprintf(stderr, "Unexpected result waiting for threads: %lu: %s\n",
                wait_result, android::base::SystemErrorCodeToString(GetLastError()).c_str());
        return -1;
    }

    // For now ignore the thread exit codes and assume they worked properly.

    if (!got_ack) {
        return -1;
    }
#else /* !defined(_WIN32) */
    // set up a pipe so the child can tell us when it is ready.
    // fd[0] will be parent's end, and the child will write on fd[1]
    int fd[2];
    if (pipe(fd)) {
        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
        return -1;
    }

    std::string path = android::base::GetExecutablePath();

    pid_t pid = fork();
    if (pid < 0) return -1;

    if (pid == 0) {
        // child side of the fork

        adb_close(fd[0]);

        char reply_fd[30];
        snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]);
        // child process
        int result = execl(path.c_str(), "adb", "-L", socket_spec.c_str(), "fork-server", "server",
                           "--reply-fd", reply_fd, NULL);
        // this should not return
        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
    } else  {
        // parent side of the fork

        char  temp[3];

        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
        // wait for the "OK\n" message
        adb_close(fd[1]);
        int ret = adb_read(fd[0], temp, 3);
        int saved_errno = errno;
        adb_close(fd[0]);
        if (ret < 0) {
            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
            return -1;
        }
        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }
    }
#endif /* !defined(_WIN32) */
    return 0;
}
Пример #21
0
 int  ScanFilesEx ( CTEXTSTR base
           , CTEXTSTR mask
           , void **pInfo
           , void CPROC Process( uintptr_t psvUser, CTEXTSTR name, int flags )
           , int flags 
           , uintptr_t psvUser 
		   , LOGICAL begin_sub_path 
		   , struct file_system_mounted_interface *mount
		   )
{
	PMFD pDataCurrent = (PMFD)(pInfo);
	PMFD pData = (PMFD)(*pInfo);
	TEXTSTR tmp_base = NULL;
	int sendflags;
	int processed = 0;
#ifndef WIN32
	struct dirent *de;
#endif
	if( begin_sub_path )
	{
		pInfo = (void**)&(pDataCurrent->current);
	}
	else
		pDataCurrent = NULL;

	//lprintf( "Search in %s for %s   %d %d", base?base:"(NULL)", mask?mask:"(*)", (*pInfo)?((PMFD)*pInfo)->scanning_mount:0, (*pInfo)?((PMFD)*pInfo)->single_mount:0 );
	if( !*pInfo || begin_sub_path || ((PMFD)*pInfo)->new_mount )
	{
		TEXTCHAR findmask[256];
		pData = (PMFD)(*pInfo);
		if( !pData )
		{
			*pInfo = Allocate( sizeof( MFD ) );
			pData = (PMFD)(*pInfo);
			if( !( pData->scanning_mount = mount ) )
			{
				if( !winfile_local )
					SimpleRegisterAndCreateGlobal( winfile_local );

				//lprintf( "... %p", winfile_local );
				pData->single_mount = FALSE;
				pData->scanning_mount = (*winfile_local).mounted_file_systems;
			}
			else
				pData->single_mount = TRUE;

			if( !pData->scanning_mount )
			{
				Deallocate( PMFD, pData );
				if( tmp_base )
					Release( tmp_base );
				return 0;
			}
			if( pData->scanning_mount->fsi )
			{
				//lprintf( "create cursor" );
				tmp_base = ExpandPathEx( base, pData->scanning_mount->fsi );
				pData->cursor = pData->scanning_mount->fsi->find_create_cursor( pData->scanning_mount->psvInstance, CStrDup( tmp_base ), CStrDup( mask ) );
			}
			else
			{
				//lprintf( "no cursor" );
				pData->cursor = NULL;
			}
		}
		else
		{
			if( pData->new_mount )
			{
				if( pData->scanning_mount->fsi )
				{
					//lprintf( "create cursor (new mount)" );
					tmp_base = ExpandPathEx( base, pData->scanning_mount->fsi );
					pData->cursor = pData->scanning_mount->fsi->find_create_cursor( pData->scanning_mount->psvInstance, CStrDup( tmp_base ), CStrDup( mask ) );
				}
				else
					pData->cursor = NULL;
			}
		}
		pData->new_mount = FALSE;
		pData->current = NULL;
		pData->prior = pDataCurrent;

		if( pDataCurrent )
		{
			pData->root_info = pDataCurrent->root_info;
			pInfo = (void**)pData->root_info;
		}
		else
		{
			pData->root_info = (struct myfinddata**)pInfo;
		}

		(*pData->root_info) = pData;
		if( base )
		{
			TEXTSTR tmp;
			StrCpyEx( findbasename(pInfo), tmp = ExpandPathEx( base, pData->scanning_mount?pData->scanning_mount->fsi:NULL ), MAX_PATH_NAME );
			Release( tmp );
			StrCpyEx( findmask(pInfo), mask, MAX_PATH_NAME );
		}
		else
		{
			CTEXTSTR p = pathrchr( mask );
			if( p )
			{
				StrCpyEx( findbasename(pInfo), mask, p - mask + 1 );
				StrCpyEx( findmask(pInfo), p + 1, MAX_PATH_NAME );
				//mask = p + 1;
			}
			else
			{
				StrCpyEx( findbasename(pInfo), WIDE(""), 2 );
				StrCpyEx( findmask(pInfo), mask, MAX_PATH_NAME );
			}
		}
		if( findbasename(pInfo)[0] )
			tnprintf( findmask, sizeof(findmask), WIDE("%s/*"), findbasename(pInfo) );
		else
			tnprintf( findmask, sizeof( findmask ), WIDE( "*" ) );
		if( pData->scanning_mount?pData->scanning_mount->fsi:NULL )
			if( pData->scanning_mount->fsi->find_first( findcursor(pInfo) ) )
				findhandle(pInfo) = 0;
			else
				findhandle(pInfo) = (HANDLECAST)-1;
		else
		{
#if WIN32
			findhandle(pInfo) = findfirst( findmask, finddata(pInfo) );
#else
			//lprintf( "opendir %s", findbasename(pInfo) );
			findhandle( pInfo ) = opendir( findbasename(pInfo) );
			if( !findhandle(pInfo ) )
				findhandle(pInfo) = (HANDLECAST)-1;
			else
				de = readdir( (DIR*)findhandle( pInfo ) );
#endif
		}
		if( findhandle(pInfo) == (HANDLECAST)-1 )
		{
			PMFD prior = pData->prior;
			//lprintf( "first use of cursor or first open of directoy failed..." );
			if( pData->scanning_mount && pData->scanning_mount->fsi )
				pData->scanning_mount->fsi->find_close( (struct find_cursor*)findcursor(pInfo) );
			else
			{
#ifdef WIN32
				findclose( findhandle(pInfo) );
#else
				// but it failed... so ... don't close
				//closedir( findhandle( pInfo ) );
#endif
			}
			pData->scanning_mount = NextThing( pData->scanning_mount );
			if( !pData->scanning_mount || pData->single_mount )
			{
				(*pData->root_info) = pData->prior;
				if( !begin_sub_path ) {
					Release( pData ); pInfo[0] = NULL;
				}
				//lprintf( WIDE( "%p %d" ), prior, processed );
				if( tmp_base )
					Release( tmp_base );
				return prior?processed:0;
			}
			pData->new_mount = TRUE;
				if( tmp_base )
					Release( tmp_base );
			return 1;
		}
	}
	else
	{
		int r;
getnext:
		//lprintf( "returning customer..." );
		if( pData->scanning_mount?pData->scanning_mount->fsi:NULL )
			r = !pData->scanning_mount->fsi->find_next( findcursor( pInfo ) );
		else
		{
#ifdef _WIN32
			r = findnext( findhandle(pInfo), finddata( pInfo ) );
#else
			de = readdir( (DIR*)findhandle( pInfo ) );
			//lprintf( "using %p got %p", findhandle( pInfo ), de );
			r = (de == NULL);
#endif
		}
		if( r )
		{
			PMFD prior = pData->prior;
			//lprintf( "nothing left to find..." );
			if( pData->scanning_mount->fsi )
				pData->scanning_mount->fsi->find_close( findcursor(pInfo) );
			else
			{
#ifdef WIN32
				findclose( findhandle(pInfo) );
#else
				closedir( (DIR*)findhandle(pInfo));
#endif
			}
			pData->scanning_mount = NextThing( pData->scanning_mount );
			//lprintf( "Step mount... %p %d", pData->scanning_mount, pData->single_mount );
			if( !pData->scanning_mount || pData->single_mount )
			{
				//lprintf( "done with mounts?" );
				(*pData->root_info) = pData->prior;
				Release( pData );
				if( prior )
					prior->current = NULL;
				if( !processed && !begin_sub_path )
				{
					//pInfo = (void**)&(prior->prior->current);
					pData = prior;
					if( pData )
						goto getnext;
				}
				if( tmp_base )
					Release( tmp_base );
				return (*pInfo)?processed:0;
			}
			pData->new_mount = TRUE;
			if( tmp_base )
				Release( tmp_base );
			return 1;
		}
	}
	if( pData->scanning_mount?pData->scanning_mount->fsi:NULL )
	{
		char * path = pData->scanning_mount->fsi->find_get_name( findcursor(pInfo) );
		//lprintf( "... %s", path );
		if( !strcmp( ".", path ) ||
		    !strcmp( "..", path ) )
		goto getnext;
	}
	else
	{
#if WIN32 
		//lprintf( "... %s", finddata(pInfo)->name );
#  ifdef UNDER_CE
		if( !StrCmp( WIDE("."), finddata(pInfo)->cFileName ) ||
		    !StrCmp( WIDE(".."), finddata(pInfo)->cFileName ) )
#  else
		if( !StrCmp( WIDE("."), finddata(pInfo)->name ) ||
		    !StrCmp( WIDE(".."), finddata(pInfo)->name ) )
#  endif
#else
		if( !StrCmp( WIDE("."), de->d_name ) ||
		    !StrCmp( WIDE(".."), de->d_name ) )
#endif
			goto getnext;
	}
	if( !(flags & SFF_NAMEONLY) ) // if nameonly - have to rebuild the correct name.
	{
		if( pData->scanning_mount?pData->scanning_mount->fsi:NULL )
		{
			tnprintf( pData->file_buffer, MAX_PATH_NAME, WIDE("%s"), pData->scanning_mount->fsi->find_get_name( findcursor(pInfo) ) );
			if( findbasename( pInfo )[0] )
				tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s/%s"), findbasename(pInfo), pData->file_buffer );
			else
				tnprintf( pData->buffer, MAX_PATH_NAME, WIDE( "%s" ), pData->file_buffer );
		}
		else
		{
#ifdef WIN32
#  ifdef UNDER_CE
			tnprintf( pData->file_buffer, MAX_PATH_NAME, WIDE( "%s" ), finddata( pInfo )->cFileName );
			tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s/%s"), findbasename(pInfo), finddata(pInfo)->cFileName );
#  else
			tnprintf( pData->file_buffer, MAX_PATH_NAME, WIDE("%s"), finddata(pInfo)->name );
			tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s%s%s"), findbasename(pInfo), findbasename( pInfo )[0]?"/":"", pData->file_buffer );
#  endif
#else
			tnprintf( pData->file_buffer, MAX_PATH_NAME, WIDE("%s"), de->d_name );
			tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s/%s"), findbasename(pInfo), de->d_name );
#endif
		}
	}
	else
	{
		if( flags & SFF_SUBCURSE )
		{
			if( pData->scanning_mount?pData->scanning_mount->fsi:NULL )
			{
				tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s%s%s")
					  , pData->prior?pData->prior->buffer:WIDE( "" )
					  , pData->prior?WIDE( "/" ):WIDE( "" )
					, pData->scanning_mount->fsi->find_get_name( findcursor(pInfo) ) 
					);
			}
			else
			{
#if WIN32
#  ifdef UNDER_CE
				tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s%s%s")
						  , pData->prior?pData->prior->buffer:WIDE( "" )
						  , pData->prior?WIDE( "/" ):WIDE( "" )
						  , finddata(pInfo)->cFileName );
#  else
				tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s%s%s")
						  , pData->prior?pData->prior->buffer:WIDE( "" )
						  , pData->prior?WIDE( "/" ):WIDE( "" )
						  , finddata(pInfo)->name );
#  endif
#else
				tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s%s%s")
					  , pData->prior?pData->prior->buffer:WIDE( "" )
					  , pData->prior?WIDE( "/" ):WIDE( "" )
					  , de->d_name );
					  lprintf( "resulting is %s", pData->buffer );
#endif
			}
		}
		else
		{
			if( pData->scanning_mount?pData->scanning_mount->fsi:NULL )
			{
				tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s"), pData->scanning_mount->fsi->find_get_name( findcursor(pInfo) ) );
			}
			else
			{
#if WIN32
#  ifdef UNDER_CE
				tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s"), finddata(pInfo)->cFileName );
#  else
#    ifdef UNICODE
				snwprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s"), finddata(pInfo)->name );
#    else
				tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s"), finddata(pInfo)->name );
#    endif
#  endif
#else
				tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s"), de->d_name );
#endif
			}
		}
	}
	pData->buffer[MAX_PATH_NAME-1] = 0; // force nul termination...
#ifdef UNICODE
	{
		char *pDataBuffer = CStrDup( pData->buffer );
#else
#  define pDataBuffer pData->buffer
#endif
	//lprintf( "Check if %s is a directory...", pData->buffer );
	if( (flags & (SFF_DIRECTORIES | SFF_SUBCURSE))
		&& (pData->scanning_mount && pData->scanning_mount->fsi
			&& (pData->scanning_mount->fsi->is_directory
				&& pData->scanning_mount->fsi->is_directory( pDataBuffer )))
		|| (!(pData->scanning_mount ? pData->scanning_mount->fsi : NULL)
#ifdef WIN32
#  ifdef UNDER_CE
			&& (finddata( pInfo )->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
#  else
			&& (finddata( pInfo )->attrib & _A_SUBDIR)
#  endif
#else
			&& IsPath( pData->buffer )
#endif
			) )
	{
#ifdef UNICODE
		Deallocate( char *, pDataBuffer );
#else 
#  undef pDataBuffer
#endif
		//lprintf( "... it is?" );
		if( flags & SFF_DIRECTORIES )
		{
			if( Process != NULL )
			{
				//lprintf( "Send %s", pData->buffer );
				Process( psvUser, pData->buffer, SFF_DIRECTORY );
				processed = 1;
			}
			//return 1;
		}
		if( flags & SFF_SUBCURSE )
		{
			void *data = NULL;
			int ofs = 0;
			TEXTCHAR tmpbuf[MAX_PATH_NAME];
			if( flags & SFF_NAMEONLY )
			{
				// even in name only - need to have this full buffer for subcurse.
				if( pData->scanning_mount && pData->scanning_mount->fsi )
				{
					ofs = tnprintf( tmpbuf, sizeof( tmpbuf ), WIDE( "%s/%s" ), findbasename( pInfo ), pData->scanning_mount->fsi->find_get_name( findcursor( pInfo ) ) );
				}
				else
				{
#ifdef WIN32
#  ifdef UNDER_CE
					ofs = tnprintf( tmpbuf, sizeof( tmpbuf ), WIDE( "%s/%s" ), findbasename( pInfo ), finddata( pInfo )->cFileName );
#  else
#    ifdef UNICODE
					ofs = snwprintf( tmpbuf, sizeof( tmpbuf ), WIDE( "%s/%s" ), findbasename( pInfo ), finddata( pInfo )->name );
#    else
					ofs = tnprintf( tmpbuf, sizeof( tmpbuf ), WIDE( "%s/%s" ), findbasename( pInfo ), finddata( pInfo )->name );
#    endif
#  endif
#else	
					ofs = tnprintf( tmpbuf, sizeof( tmpbuf ), WIDE( "%s/%s" ), findbasename( pInfo ), de->d_name );
#endif
				}
				//lprintf( "process sub... %s %s", tmpbuf, findmask(pInfo)  );
				processed |= ScanFilesEx( tmpbuf, findmask( pInfo ), (POINTER*)pData, Process, flags, psvUser, TRUE, pData->scanning_mount );
			}
			else
			{
				//lprintf( "process sub..." );
				processed |= ScanFilesEx( pData->buffer, findmask( pInfo ), (POINTER*)pData, Process, flags, psvUser, TRUE, pData->scanning_mount );
			}
		}
		if( !processed )
			goto getnext;
		if( tmp_base )
			Release( tmp_base );
		return (*pInfo) ? 1 : 0;
	}
#ifdef UNICODE
	Deallocate( char *, pDataBuffer );
	}
#else 
#  undef pDataBuffer
#endif
	if( ( sendflags = SFF_DIRECTORY, ( ( flags & SFF_DIRECTORIES )
#ifdef WIN32
#  ifdef UNDER_CE
												 && ( finddata(pInfo)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
#  else
												 && ( finddata(pInfo)->attrib & _A_SUBDIR )
#  endif
#else
												 && ( IsPath( pData->buffer ) )

#endif
												) ) || ( sendflags = 0, CompareMask( findmask( pInfo )
#ifdef WIN32
#  ifdef UNDER_CE
																							  , finddata(pInfo)->cFileName
#  else
																							  , pData->file_buffer
#  endif
#else
																							  , de->d_name
#endif
																								// yes this is silly - but it's correct...
																							  , (flags & SFF_IGNORECASE)?0:0 ) ) )
	{
		//lprintf( "Send %s", pData->buffer );
		if( Process != NULL )
			Process( psvUser, pData->buffer, sendflags );
		if( tmp_base )
			Release( tmp_base );
		return (*pInfo)?1:0;
	}
	if( tmp_base )
		Release( tmp_base );
	return (*pInfo)?1:0;
}
Пример #22
0
int launch_server(int server_port)
{
#if defined(_WIN32)
    /* we need to start the server in the background                    */
    /* we create a PIPE that will be used to wait for the server's "OK" */
    /* message since the pipe handles must be inheritable, we use a     */
    /* security attribute                                               */
    HANDLE                nul_read, nul_write;
    HANDLE                pipe_read, pipe_write;
    HANDLE                stdout_handle, stderr_handle;
    SECURITY_ATTRIBUTES   sa;
    STARTUPINFOW          startup;
    PROCESS_INFORMATION   pinfo;
    WCHAR                 program_path[ MAX_PATH ];
    int                   ret;

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /* Redirect stdin and stderr to Windows /dev/null. If we instead pass our
     * stdin/stderr handles and they are console handles, when the adb server
     * starts up, the C Runtime will see console handles for a process that
     * isn't connected to a console and it will configure stderr to be closed.
     * At that point, freopen() could be used to reopen stderr, but it would
     * take more massaging to fixup the file descriptor number that freopen()
     * uses. It's simplest to avoid all of this complexity by just redirecting
     * stdin/stderr to `nul' and then the C Runtime acts as expected.
     */
    nul_read = CreateFileW(L"nul", GENERIC_READ,
                           FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (nul_read == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "CreateFileW(nul, GENERIC_READ) failed: %s\n",
                SystemErrorCodeToString(GetLastError()).c_str());
        return -1;
    }

    nul_write = CreateFileW(L"nul", GENERIC_WRITE,
                            FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (nul_write == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "CreateFileW(nul, GENERIC_WRITE) failed: %s\n",
                SystemErrorCodeToString(GetLastError()).c_str());
        CloseHandle(nul_read);
        return -1;
    }

    /* create pipe, and ensure its read handle isn't inheritable */
    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
    if (!ret) {
        fprintf(stderr, "CreatePipe() failed: %s\n",
                SystemErrorCodeToString(GetLastError()).c_str());
        CloseHandle(nul_read);
        CloseHandle(nul_write);
        return -1;
    }

    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );

    /* Some programs want to launch an adb command and collect its output by
     * calling CreateProcess with inheritable stdout/stderr handles, then
     * using read() to get its output. When this happens, the stdout/stderr
     * handles passed to the adb client process will also be inheritable.
     * When starting the adb server here, care must be taken to reset them
     * to non-inheritable.
     * Otherwise, something bad happens: even if the adb command completes,
     * the calling process is stuck while read()-ing from the stdout/stderr
     * descriptors, because they're connected to corresponding handles in the
     * adb server process (even if the latter never uses/writes to them).
     */
    stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
    stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
    if (stdout_handle != INVALID_HANDLE_VALUE) {
        SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
    }
    if (stderr_handle != INVALID_HANDLE_VALUE) {
        SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
    }

    ZeroMemory( &startup, sizeof(startup) );
    startup.cb = sizeof(startup);
    startup.hStdInput  = nul_read;
    startup.hStdOutput = pipe_write;
    startup.hStdError  = nul_write;
    startup.dwFlags    = STARTF_USESTDHANDLES;

    ZeroMemory( &pinfo, sizeof(pinfo) );

    /* get path of current program */
    DWORD module_result = GetModuleFileNameW(NULL, program_path,
                          arraysize(program_path));
    if ((module_result == arraysize(program_path)) || (module_result == 0)) {
        // String truncation or some other error.
        fprintf(stderr, "GetModuleFileNameW() failed: %s\n",
                SystemErrorCodeToString(GetLastError()).c_str());
        return -1;
    }
    WCHAR args[64];
    snwprintf(args, arraysize(args),
              L"adb -P %d fork-server server", server_port);
    ret = CreateProcessW(
              program_path,                              /* program path  */
              args,
              /* the fork-server argument will set the
                 debug = 2 in the child           */
              NULL,                   /* process handle is not inheritable */
              NULL,                    /* thread handle is not inheritable */
              TRUE,                          /* yes, inherit some handles */
              DETACHED_PROCESS, /* the new process doesn't have a console */
              NULL,                     /* use parent's environment block */
              NULL,                    /* use parent's starting directory */
              &startup,                 /* startup info, i.e. std handles */
              &pinfo );

    CloseHandle( nul_read );
    CloseHandle( nul_write );
    CloseHandle( pipe_write );

    if (!ret) {
        fprintf(stderr, "CreateProcess failed: %s\n",
                SystemErrorCodeToString(GetLastError()).c_str());
        CloseHandle( pipe_read );
        return -1;
    }

    CloseHandle( pinfo.hProcess );
    CloseHandle( pinfo.hThread );

    /* wait for the "OK\n" message */
    {
        char  temp[3];
        DWORD  count;

        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
        CloseHandle( pipe_read );
        if ( !ret ) {
            fprintf(stderr, "could not read ok from ADB Server, error: %s\n",
                    SystemErrorCodeToString(GetLastError()).c_str());
            return -1;
        }
        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }
    }
#else /* !defined(_WIN32) */
    char    path[PATH_MAX];
    int     fd[2];

    // set up a pipe so the child can tell us when it is ready.
    // fd[0] will be parent's end, and the child will write on fd[1]
    if (pipe(fd)) {
        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
        return -1;
    }
    get_my_path(path, PATH_MAX);
    pid_t pid = fork();
    if(pid < 0) return -1;

    if (pid == 0) {
        // child side of the fork

        adb_close(fd[0]);

        char str_port[30];
        snprintf(str_port, sizeof(str_port), "%d", server_port);
        char reply_fd[30];
        snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]);
        // child process
        int result = execl(path, "adb", "-P", str_port, "fork-server", "server", "--reply-fd", reply_fd, NULL);
        // this should not return
        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
    } else  {
        // parent side of the fork

        char  temp[3];

        temp[0] = 'A';
        temp[1] = 'B';
        temp[2] = 'C';
        // wait for the "OK\n" message
        adb_close(fd[1]);
        int ret = adb_read(fd[0], temp, 3);
        int saved_errno = errno;
        adb_close(fd[0]);
        if (ret < 0) {
            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
            return -1;
        }
        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }

        setsid();
    }
#endif /* !defined(_WIN32) */
    return 0;
}
Пример #23
0
int convert_h3c(const wchar_t *src_path, const wchar_t *filename, const wchar_t *dest_path, convert_cb_t cb, void *cb_data)
{
    h3clib_ctx_t h3c = NULL;
    wchar_t fullpath[MAX_PATH] = { 0 };
    wchar_t fullpath_out[MAX_PATH] = { 0 };
    const wchar_t *version_src = L"unknown";
    const wchar_t *version_dst = L"unknown";
    enum H3M_FORMAT fm_src = 0;
    int ret = 0;
    int result = 0;

    snwprintf(fullpath, sizeof(fullpath) / sizeof(fullpath[0])-1, L"%s\\%s", src_path, filename);

    h3c_read_convert_u(&h3c, fullpath, 0, &fm_src, NULL, NULL);

    // Error check, if h3c is NULL then conversion failed
    if (NULL == h3c) {
        if (NULL != cb) {

            switch (fm_src)
            {
            case H3C_FORMAT_SOD:
            case H3C_FORMAT_CHR:
                result = CONVERT_RESULT_FAIL;
                break;
            default:
                CONVERT_RESULT_SKIP;
                break;
            }

            if (0 != (ret = cb(filename, fm_src, result, cb_data))) {
                return ret;
            }
        }

        return 0;
    }

    switch (fm_src)
    {
    case H3C_FORMAT_SOD:
        version_src = L"SoD";
        version_dst = L"CHR";
        break;
    case H3C_FORMAT_CHR:
        version_src = L"CHR";
        version_dst = L"SoD";
        break;
    default:
        break;
    }

    snwprintf(fullpath_out, sizeof(fullpath_out) / sizeof(fullpath_out[0]) - 1, 
        L"%s\\[%s-%s] %s", dest_path, version_src, version_dst, filename);

    h3c_write_u(h3c, fullpath_out);
    //h3m_compress(fullpath_out, fullpath_out);

    h3c_exit(&h3c);

    if (NULL != cb) {
        if (0 != (ret = cb(filename, fm_src, CONVERT_RESULT_SUCCESS, cb_data))) {
            return ret;
        }
    }

    return 0;
}
Пример #24
0
/*
 * Validate options against a white list. Also check the config_file is
 * inside the config_dir. The white list is defined in validate.c
 * Returns true on success
 */
static BOOL
ValidateOptions (HANDLE pipe, const WCHAR *workdir, const WCHAR *options)
{
    WCHAR **argv;
    int argc;
    WCHAR buf[256];
    BOOL ret = FALSE;
    int i;
    const WCHAR *msg1 = L"You have specified a config file location (%s relative to %s)"
                        " that requires admin approval. This error may be avoided"
                        " by adding your account to the \"%s\" group";

    const WCHAR *msg2 = L"You have specified an option (%s) that may be used"
                         " only with admin approval. This error may be avoided"
                         " by adding your account to the \"%s\" group";

    argv = CommandLineToArgvW (options, &argc);

    if (!argv)
    {
        ReturnLastError (pipe, L"CommandLineToArgvW");
        ReturnError (pipe, ERROR_STARTUP_DATA, L"Cannot validate options", 1, &exit_event);
        goto out;
    }

    /* Note: argv[0] is the first option */
    if (argc < 1)  /* no options */
    {
        ret = TRUE;
        goto out;
    }

    /*
     * If only one argument, it is the config file
     */
    if (argc == 1)
    {
        WCHAR *argv_tmp[2] = { L"--config", argv[0] };

        if (!CheckOption (workdir, 2, argv_tmp, &settings))
        {
            snwprintf (buf, _countof(buf), msg1, argv[0], workdir,
                       settings.ovpn_admin_group);
            buf[_countof(buf) - 1] = L'\0';
            ReturnError (pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
        }
        goto out;
    }

    for (i = 0; i < argc; ++i)
    {
        if (!IsOption(argv[i]))
            continue;

        if (!CheckOption (workdir, argc-i, &argv[i], &settings))
        {
            if (wcscmp(L"--config", argv[i]) == 0 && argc-i > 1)
            {
                snwprintf (buf, _countof(buf), msg1, argv[i+1], workdir,
                            settings.ovpn_admin_group);
                buf[_countof(buf) - 1] = L'\0';
                ReturnError (pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
            }
            else
            {
                snwprintf (buf, _countof(buf), msg2, argv[i],
                           settings.ovpn_admin_group);
                buf[_countof(buf) - 1] = L'\0';
                ReturnError (pipe, ERROR_STARTUP_DATA, buf, 1, &exit_event);
            }
            goto out;
        }
    }

    /* all options passed */
    ret = TRUE;

out:
    if (argv)
        LocalFree (argv);
    return ret;
}
Пример #25
0
void plCreateMenu()
{
#if MAX_VERSION_MAJOR <= 11
    AddPlasmaExportMenu();
#endif

    IMenuManager* pMenuMan = GetCOREInterface()->GetMenuManager();
    bool newlyRegistered = pMenuMan->RegisterMenuBarContext(kMyMenuContextId, kMenuName);

    // Is the Max menu version the most recent?
    bool wrongVersion = GetPrivateProfileIntW(L"Menu", L"Version", 0, plMaxConfig::GetPluginIni().WideString().data()) < kMenuVersion;
    if (wrongVersion)
    {
        // Delete the old version of the menu
        IMenu *oldMenu = pMenuMan->FindMenu(kMenuName);
        if (oldMenu)
            pMenuMan->UnRegisterMenu(oldMenu);

        // Update the menu version
        wchar_t buf[12];
        snwprintf(buf, arrsize(buf), L"%d", kMenuVersion);
        WritePrivateProfileStringW(L"Menu", L"Version", buf, plMaxConfig::GetPluginIni().WideString().data());
    }
    
    if (wrongVersion || newlyRegistered)
    {
        IMenu *pMainMenu = pMenuMan->GetMainMenuBar();
        if (!pMainMenu)
        {
            hsAssert(0, "Main menu not found");
            return;
        }

        // Get our action table
        ActionTable* pActionTable = GetCOREInterface()->GetActionManager()->FindTable(kActionId);
        if (!pActionTable)
        {
            hsAssert(0, "Action table not found");
            return;
        }

        // Create the Plasma menu
        IMenu* pPlasmaMenu = GetIMenu();
        pPlasmaMenu->SetTitle(kMenuName);

        // Register the new menu with the system
        pMenuMan->RegisterMenu(pPlasmaMenu, 0);

        /////////////////////////////////////////////////
        // Add the menu items
        //
        IMenuItem* pMenuItem;
 
#if MAX_VERSION_MAJOR >= 12
        // Add the export action to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionExport));
        pPlasmaMenu->AddItem(pMenuItem);
#endif

        // Add the save selected action to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionSaveSel));
        pPlasmaMenu->AddItem(pMenuItem);

        // Add the merge action to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionMerge));
        pPlasmaMenu->AddItem(pMenuItem);

        // Add the component copy action to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionCompCopy));
        pPlasmaMenu->AddItem(pMenuItem);

        // Add a separator
        pMenuItem = GetIMenuItem();
        pMenuItem->ActAsSeparator();
        pPlasmaMenu->AddItem(pMenuItem);
    
        // Add the component manager to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionComponent));
        pPlasmaMenu->AddItem(pMenuItem);

        // Add the resource collector to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionResCollect));
        pPlasmaMenu->AddItem(pMenuItem);

        // Add the texture search to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionTexSearch));
        pPlasmaMenu->AddItem(pMenuItem);

        // Add the age description to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionAgeDesc));
        pPlasmaMenu->AddItem(pMenuItem);

        // Add a separator
        pMenuItem = GetIMenuItem();
        pMenuItem->ActAsSeparator();
        pPlasmaMenu->AddItem(pMenuItem);

        // Add the Lock Selected to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionLock));
        pPlasmaMenu->AddItem(pMenuItem);

        // Add the Unlock Selected to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionUnlock));
        pPlasmaMenu->AddItem(pMenuItem);

        // Add the Reset Selected to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionReset));
        pPlasmaMenu->AddItem(pMenuItem);

        // Add the SelectNonRenderables to the menu
        pMenuItem = GetIMenuItem();
        pMenuItem->SetActionItem(pActionTable->GetAction(kActionSelectNonRenderables));
        pPlasmaMenu->AddItem(pMenuItem);

        // Create a new menu item to hold the sub-menu
        IMenuItem* pSubMenuItem1 = GetIMenuItem();   //menu in menu bar...
        pSubMenuItem1->SetSubMenu(pPlasmaMenu);
        pMainMenu->AddItem(pSubMenuItem1);

        pMenuMan->UpdateMenuBar();

        // Save the dang menu, in case Max crashes
        const char *uiDir = GetCOREInterface()->GetDir(APP_UI_DIR);
        char path[MAX_PATH];
        sprintf(path, "%s\\%s", uiDir, "MaxMenus.mnu");
        
        pMenuMan->SaveMenuFile(path);
    }

}
Пример #26
0
int ISO8601::ToString(const struct tm& value, wchar_t *wstr, int *wlen)
{
	//2010-06-08T14:26:23Z
	*wlen = snwprintf(wstr, *wlen, L"%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ", (1900 + value.tm_year), (1 + value.tm_mon), value.tm_mday, value.tm_hour, value.tm_min, value.tm_sec);
	return (errno = 0);
}