Example #1
0
static const wchar_t *GetLastCharactercW(const wchar_t *string)
{
	if (!string || !*string)
		return string;

	return CharPrevW(string, string+lstrlenW(string));
}
Example #2
0
static const wchar_t *scanstr_backW(const wchar_t *str, const wchar_t *toscan, const wchar_t *defval)
{
	const wchar_t *s = GetLastCharactercW(str);
	if (!str[0]) return defval;
	if (!toscan || !toscan[0]) return defval; 
	while (1)
	{
		const wchar_t *t = toscan;
		while (*t)
		{
			if (*t == *s) return s;
			t = CharNextW(t);
		}
		t = CharPrevW(str, s);
		if (t == s)
			return defval;
		s = t;
	}
}
Example #3
0
// 1つ目の引数だけファイルとして扱い、実行する。
//
// コマンドは こんな感じで連結されます。
//  exe linkpath linkarg cmdarg2 cmdarg3 cmdarg4 ...
//
static HRESULT HookAndExecute(int show)
{
   int     argc = 0;
   LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
   if(!argv) {
      return HresultFromLastError();
   }
   if(argc <= 1) {
      char buffer [256];
      LoadStringA(GetModuleHandleA(NULL), IDS_USAGE, buffer, 256);
      MessageBoxA(NULL,
         buffer
         ,"gdi++", MB_OK|MB_ICONINFORMATION);
      LocalFree(argv);
      return S_OK;
   }

   int i;
   size_t length = 1;
   for(i=2; i<argc; i++) {
      length += wcslen(argv[i]) + 3;
   }

   LPWSTR cmdline = (WCHAR*)calloc(sizeof(WCHAR), length);
   if(!cmdline) {
      LocalFree(argv);
      return E_OUTOFMEMORY;
   }

   LPWSTR p = cmdline;
   *p = L'\0';
   for(i=2; i<argc; i++) {
      const bool dq = !!wcschr(argv[i], L' ');
      if (dq) {
         *p++ = '"';
         length--;
      }
      StringCchCopyExW(p, length, argv[i], &p, &length, STRSAFE_NO_TRUNCATION);
      if (dq) {
         *p++ = '"';
         length--;
      }
      *p++ = L' ';
      length--;
   }

   *CharPrevW(cmdline, p) = L'\0';

   WCHAR file[MAX_PATH], dir[MAX_PATH];
   GetCurrentDirectoryW(_countof(dir), dir);
   StringCchCopyW(file, _countof(file), argv[1]);
   if(PathIsRelativeW(file)) {
      PathCombineW(file, dir, file);
   } else {
      WCHAR gdippDir[MAX_PATH];
      GetModuleFileNameW(NULL, gdippDir, _countof(gdippDir));
      PathRemoveFileSpec(gdippDir);

      // カレントディレクトリがgdi++.exeの置かれているディレクトリと同じだったら、
      // 起動しようとしているEXEのフルパスから抜き出したディレクトリ名をカレント
      // ディレクトリとして起動する。(カレントディレクトリがEXEと同じ場所である
      // 前提で作られているアプリ対策)
      if (wcscmp(dir, gdippDir) == 0) {
         StringCchCopyW(dir, _countof(dir), argv[1]);
         PathRemoveFileSpec(dir);
      }
   }

   LocalFree(argv);
   argv = NULL;

#ifdef _DEBUG
   if((GetAsyncKeyState(VK_CONTROL) & 0x8000)
         && MessageBoxW(NULL, cmdline, NULL, MB_YESNO) != IDYES) {
      free(cmdline);
      return NOERROR;
   }
#endif

   LPITEMIDLIST pidl = NULL;
   HRESULT hr;

   //fileのアイテムIDリストを取得
   hr = _SHILCreateFromPath(file, &pidl, NULL);
   if(SUCCEEDED(hr) && pidl) {
      //SEE_MASK_INVOKEIDLISTを使うと
      //explorerでクリックして起動したのと同じ動作になる
      SHELLEXECUTEINFOW sei = { sizeof(SHELLEXECUTEINFOW) };
      sei.fMask         = SEE_MASK_INVOKEIDLIST
                        | SEE_MASK_CONNECTNETDRV
                        | SEE_MASK_FLAG_DDEWAIT
                        | SEE_MASK_DOENVSUBST
                        | SEE_MASK_WAITFORINPUTIDLE;
      sei.hwnd       = GetDesktopWindow();
      sei.lpParameters  = cmdline;
      sei.lpDirectory      = dir;
      sei.nShow         = show;
      sei.lpIDList      = pidl;

      //ShellExecuteExWが内部で呼び出すCreateProcessWをフックして
      //HookChildProcesses相当の処理を行う

      DetourTransactionBegin();
      DetourUpdateThread(GetCurrentThread());
      DetourAttach(&(PVOID&)ORIG_CreateProcessW, IMPL_CreateProcessW);
      hr = DetourTransactionCommit();

      if(hr == NOERROR) {
         if(ShellExecuteExW(&sei)) {
            hr = S_OK;
         } else {
            hr = HresultFromLastError();
         }
      }

      DetourTransactionBegin();
      DetourUpdateThread(GetCurrentThread());
      DetourDetach(&(PVOID&)ORIG_CreateProcessW, IMPL_CreateProcessW);
      DetourTransactionCommit();
   }

   if(pidl)
      _SHFree(pidl);
   free(cmdline);
   return hr;
}
const WChar * String::PrevCharW( const WChar * inStart, const WChar * inStr ) const
{
    return CharPrevW( inStart, inStr );
}
Example #5
0
static BOOL _CopyAndUnquoteText(LPCWSTR strFieldSource, LPWSTR strField, size_t cchField)
{
    WCHAR cChar;
    PWSTR tmpField = strField;
    size_t lenField = 1;
    BOOL inQuote = FALSE;

    // Remove leading whitespace
    cChar = *strFieldSource;
    while (cChar == L' ' || cChar == L'\t' || cChar == L'\n' || cChar == L'\r')
    {
        strFieldSource = CharNextW(strFieldSource);
        cChar = *strFieldSource;
    }

    while (cChar && cChar != L'=' && cChar != L',')
    {
        if (cChar == L'"')
        {
            // [1] is always valid read because of null-termination
            if (inQuote && strFieldSource[1] == L'"')
            {
                if (lenField < cchField)
                {
                    // Append
                    *(tmpField++) = L'"';
                    ++lenField;
                }

                // Skip second quote
                strFieldSource++;
            }
            else
            {
                inQuote = !inQuote;
            }
        }
        else
        {
            if (inQuote || (cChar != L'=' && cChar != L','))
            {
                if (lenField < cchField)
                {
                    // Append
                    *(tmpField++) = cChar;
                    ++lenField;
                }
            }
        }

        strFieldSource = CharNextW(strFieldSource);
        cChar = *strFieldSource;
    }

    // Remove trailing whitespace
    while (tmpField > strField)
    {
        tmpField = CharPrevW(strField, tmpField);
        cChar = *tmpField;
        if (cChar != L' ' && cChar != L'\t' && cChar != L'\n' && cChar != L'\r')
        {
            tmpField = CharNextW(tmpField);
            break;
        }
    }

    // Terminate output string
    *tmpField = 0;

    return TRUE;
}