1 // SoftEther UT-VPN SourceCode
\r
3 // Copyright (C) 2004-2010 SoftEther Corporation.
\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.
\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.
\r
6 // All Rights Reserved.
\r
8 // http://utvpn.tsukuba.ac.jp/
\r
10 // This program is free software; you can redistribute it and/or
\r
11 // modify it under the terms of the GNU General Public License
\r
12 // version 2 as published by the Free Software Foundation.
\r
14 // This program is distributed in the hope that it will be useful,
\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 // GNU General Public License for more details.
\r
19 // You should have received a copy of the GNU General Public License version 2
\r
20 // along with this program; if not, write to the Free Software
\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。
\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の
\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
\r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
\r
34 // および、試験または研究のために利用が行われることを想定して配布
\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
\r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
\r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。
\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
\r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の
\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
\r
58 // 公益保護にご協力いただきますようお願い申し上げます。
\r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
\r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
\r
65 // 日本国内の脆弱性情報届出受付公的機関:
\r
67 // http://www.ipa.go.jp/security/vuln/report/
\r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/
\r
72 // -----------------------------------------------
\r
75 // 新規リリース by SoftEther
\r
76 // -----------------------------------------------
\r
79 // Microsoft Windows 依存コード
\r
83 #define _WIN32_WINNT 0x0502
\r
84 #define WINVER 0x0502
\r
85 #include <winsock2.h>
\r
86 #include <windows.h>
\r
87 #include <Dbghelp.h>
\r
88 #include <commctrl.h>
\r
89 #include <process.h>
\r
97 #include <Mayaqua/Mayaqua.h>
\r
99 static HANDLE heap_handle = NULL;
\r
100 static HANDLE hstdout = INVALID_HANDLE_VALUE;
\r
101 static HANDLE hstdin = INVALID_HANDLE_VALUE;
\r
104 typedef struct WIN32THREAD
\r
111 typedef struct WIN32THREADSTARTUPINFO
\r
113 THREAD_PROC *thread_proc;
\r
116 } WIN32THREADSTARTUPINFO;
\r
119 DWORD CALLBACK Win32DefaultThreadProc(void *param);
\r
122 static HANDLE hCurrentProcessHandle = NULL;
\r
123 static CRITICAL_SECTION fasttick_lock;
\r
124 static UINT64 start_tick = 0;
\r
125 static bool use_heap_api = false;
\r
126 static bool win32_is_nt = false;
\r
128 // Win32 用ファイル I/O データ
\r
129 typedef struct WIN32IO
\r
135 // Win32 用ミューテックスデータ
\r
136 typedef struct WIN32MUTEX
\r
142 OS_DISPATCH_TABLE *Win32GetDispatchTable()
\r
144 static OS_DISPATCH_TABLE t =
\r
149 Win32MemoryReAlloc,
\r
152 Win32GetSystemTime,
\r
186 Win32GetCallStackSymbolInfo,
\r
191 Win32IsSupportedOs,
\r
196 Win32SetHighPriority,
\r
197 Win32RestorePriority,
\r
198 Win32NewSingleInstance,
\r
199 Win32FreeSingleInstance,
\r
208 void Win32InitNewThread()
\r
210 static HINSTANCE hDll = NULL;
\r
211 static bool (WINAPI *_SetThreadLocale)(LCID) = NULL;
\r
215 hDll = LoadLibrary("kernel32.dll");
\r
218 (bool (__stdcall *)(LCID))
\r
219 GetProcAddress(hDll, "SetThreadLocale");
\r
222 if (_SetThreadLocale != NULL)
\r
224 _SetThreadLocale(LOCALE_USER_DEFAULT);
\r
229 bool Win32SetFolderCompressW(wchar_t *path, bool compressed)
\r
234 wchar_t tmp[MAX_PATH];
\r
241 if (IsNt() == false)
\r
243 char *path_a = CopyUniToStr(path);
\r
244 bool ret = Win32SetFolderCompress(path_a, compressed);
\r
251 InnerFilePathW(tmp, sizeof(tmp), path);
\r
254 h = CreateFileW(tmp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
\r
256 if (h == INVALID_HANDLE_VALUE)
\r
261 flag = compressed ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE;
\r
263 if (DeviceIoControl(h, FSCTL_SET_COMPRESSION, &flag, sizeof(USHORT),
\r
264 NULL, 0, &retsize, NULL) == false)
\r
273 bool Win32SetFolderCompress(char *path, bool compressed)
\r
278 char tmp[MAX_PATH];
\r
285 InnerFilePath(tmp, sizeof(tmp), path);
\r
288 h = CreateFile(tmp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
\r
290 if (h == INVALID_HANDLE_VALUE)
\r
295 flag = compressed ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE;
\r
297 if (DeviceIoControl(h, FSCTL_SET_COMPRESSION, &flag, sizeof(USHORT),
\r
298 NULL, 0, &retsize, NULL) == false)
\r
309 bool Win32GetDiskFreeW(wchar_t *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)
\r
311 wchar_t tmp[MAX_SIZE];
\r
314 ULARGE_INTEGER v1, v2, v3;
\r
322 if (IsNt() == false)
\r
325 char *path_a = CopyUniToStr(path);
\r
327 ret = Win32GetDiskFree(path_a, free_size, used_size, total_size);
\r
334 Zero(&v1, sizeof(v1));
\r
335 Zero(&v2, sizeof(v2));
\r
336 Zero(&v3, sizeof(v3));
\r
338 NormalizePathW(tmp, sizeof(tmp), path);
\r
341 if (UniStartWith(path, L"\\\\"))
\r
350 len = UniStrLen(tmp);
\r
352 for (i = 0;i < len;i++)
\r
354 if (tmp[i] == L'\\')
\r
365 if (GetDiskFreeSpaceExW(tmp, &v1, &v2, &v3))
\r
370 if (free_size != NULL)
\r
372 *free_size = v1.QuadPart;
\r
375 if (total_size != NULL)
\r
377 *total_size = v2.QuadPart;
\r
380 if (used_size != NULL)
\r
382 *used_size = v2.QuadPart - v1.QuadPart;
\r
387 bool Win32GetDiskFree(char *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)
\r
389 char tmp[MAX_SIZE];
\r
392 ULARGE_INTEGER v1, v2, v3;
\r
400 Zero(&v1, sizeof(v1));
\r
401 Zero(&v2, sizeof(v2));
\r
402 Zero(&v3, sizeof(v3));
\r
404 NormalizePath(tmp, sizeof(tmp), path);
\r
407 if (StartWith(path, "\\\\"))
\r
418 for (i = 0;i < len;i++)
\r
420 if (tmp[i] == '\\')
\r
431 if (GetDiskFreeSpaceEx(tmp, &v1, &v2, &v3))
\r
436 if (free_size != NULL)
\r
438 *free_size = v1.QuadPart;
\r
441 if (total_size != NULL)
\r
443 *total_size = v2.QuadPart;
\r
446 if (used_size != NULL)
\r
448 *used_size = v2.QuadPart - v1.QuadPart;
\r
455 DIRLIST *Win32EnumDirEx(char *dirname, COMPARE *compare)
\r
458 wchar_t *dirname_w = CopyStrToUni(dirname);
\r
460 ret = Win32EnumDirExW(dirname_w, compare);
\r
466 DIRLIST *Win32EnumDirExW(wchar_t *dirname, COMPARE *compare)
\r
468 WIN32_FIND_DATAA data_a;
\r
469 WIN32_FIND_DATAW data_w;
\r
471 wchar_t tmp[MAX_PATH];
\r
472 wchar_t tmp2[MAX_PATH];
\r
473 wchar_t dirname2[MAX_PATH];
\r
477 UniStrCpy(tmp2, sizeof(tmp2), dirname);
\r
479 if (UniStrLen(tmp2) >= 1 && tmp[UniStrLen(tmp2) - 1] == L'\\')
\r
481 tmp2[UniStrLen(tmp2) - 1] = 0;
\r
484 UniFormat(tmp, sizeof(tmp), L"%s\\*.*", tmp2);
\r
485 NormalizePathW(tmp, sizeof(tmp), tmp);
\r
486 NormalizePathW(dirname2, sizeof(dirname2), tmp2);
\r
488 o = NewListFast(compare);
\r
490 Zero(&data_a, sizeof(data_a));
\r
491 Zero(&data_w, sizeof(data_w));
\r
495 h = FindFirstFileW(tmp, &data_w);
\r
499 char *tmp_a = CopyUniToStr(tmp);
\r
501 h = FindFirstFileA(tmp_a, &data_a);
\r
506 if (h != INVALID_HANDLE_VALUE)
\r
512 if (IsNt() == false)
\r
514 Zero(&data_w, sizeof(data_w));
\r
515 StrToUni(data_w.cFileName, sizeof(data_w.cFileName), data_a.cFileName);
\r
516 data_w.dwFileAttributes = data_a.dwFileAttributes;
\r
517 data_w.ftCreationTime = data_a.ftCreationTime;
\r
518 data_w.ftLastWriteTime = data_a.ftLastWriteTime;
\r
519 data_w.nFileSizeHigh = data_a.nFileSizeHigh;
\r
520 data_w.nFileSizeLow = data_a.nFileSizeLow;
\r
523 if (UniStrCmpi(data_w.cFileName, L"..") != 0 &&
\r
524 UniStrCmpi(data_w.cFileName, L".") != 0)
\r
526 DIRENT *f = ZeroMalloc(sizeof(DIRENT));
\r
528 wchar_t fullpath[MAX_SIZE];
\r
531 f->FileNameW = UniCopyStr(data_w.cFileName);
\r
532 f->FileName = CopyUniToStr(f->FileNameW);
\r
533 f->Folder = (data_w.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false;
\r
535 CombinePathW(fullpath, sizeof(fullpath), dirname2, f->FileNameW);
\r
540 HANDLE h = CreateFileW(fullpath, 0,
\r
541 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
\r
542 NULL, OPEN_EXISTING, 0, NULL);
\r
544 if (h != INVALID_HANDLE_VALUE)
\r
546 BY_HANDLE_FILE_INFORMATION info;
\r
548 Zero(&info, sizeof(info));
\r
550 if (MsGetFileInformation(h, &info))
\r
552 Zero(&t1, sizeof(t1));
\r
553 Zero(&t2, sizeof(t2));
\r
554 FileTimeToSystemTime(&info.ftCreationTime, &t1);
\r
555 FileTimeToSystemTime(&info.ftLastWriteTime, &t2);
\r
556 f->CreateDate = SystemToUINT64(&t1);
\r
557 f->UpdateDate = SystemToUINT64(&t2);
\r
559 if (f->Folder == false)
\r
561 f->FileSize = ((UINT64)info.nFileSizeHigh * (UINT64)((UINT64)MAXDWORD + (UINT64)1)) + (UINT64)info.nFileSizeLow;
\r
573 Zero(&t1, sizeof(t1));
\r
574 Zero(&t2, sizeof(t2));
\r
575 FileTimeToSystemTime(&data_w.ftCreationTime, &t1);
\r
576 FileTimeToSystemTime(&data_w.ftLastWriteTime, &t2);
\r
577 f->CreateDate = SystemToUINT64(&t1);
\r
578 f->UpdateDate = SystemToUINT64(&t2);
\r
580 if (f->Folder == false)
\r
582 f->FileSize = ((UINT64)data_w.nFileSizeHigh * (UINT64)((UINT64)MAXDWORD + (UINT64)1)) + (UINT64)data_w.nFileSizeLow;
\r
589 Zero(&data_w, sizeof(data_w));
\r
590 Zero(&data_a, sizeof(data_a));
\r
594 b = FindNextFileW(h, &data_w);
\r
598 b = FindNextFileA(h, &data_a);
\r
608 d = ZeroMalloc(sizeof(DIRLIST));
\r
609 d->NumFiles = LIST_NUM(o);
\r
610 d->File = ToArray(o);
\r
618 void Win32GetExeNameW(wchar_t *name, UINT size)
\r
626 if (IsNt() == false)
\r
628 char name_a[MAX_PATH];
\r
630 Win32GetExeName(name_a, sizeof(name_a));
\r
632 StrToUni(name, size, name_a);
\r
637 UniStrCpy(name, size, L"");
\r
639 GetModuleFileNameW(NULL, name, size);
\r
641 void Win32GetExeName(char *name, UINT size)
\r
649 StrCpy(name, size, "");
\r
651 GetModuleFileName(NULL, name, size);
\r
655 void Win32GetCurrentDirW(wchar_t *dir, UINT size)
\r
663 if (IsNt() == false)
\r
665 char dir_a[MAX_PATH];
\r
667 Win32GetCurrentDir(dir_a, sizeof(dir_a));
\r
669 StrToUni(dir, size, dir_a);
\r
674 GetCurrentDirectoryW(size, dir);
\r
676 void Win32GetCurrentDir(char *dir, UINT size)
\r
684 GetCurrentDirectory(size, dir);
\r
694 void Win32GetMemInfo(MEMINFO *info)
\r
703 Zero(info, sizeof(MEMINFO));
\r
704 Zero(&st, sizeof(st));
\r
705 st.dwLength = sizeof(st);
\r
707 GlobalMemoryStatus(&st);
\r
710 info->TotalMemory = (UINT64)st.dwTotalPageFile;
\r
711 info->FreeMemory = (UINT64)st.dwAvailPageFile;
\r
712 info->UsedMemory = info->TotalMemory - info->FreeMemory;
\r
715 info->TotalPhys = (UINT64)st.dwTotalPhys;
\r
716 info->FreePhys = (UINT64)st.dwAvailPhys;
\r
717 info->UsedPhys = info->TotalPhys - info->FreePhys;
\r
721 void *Win32NewSingleInstance(char *instance_name)
\r
724 char tmp[MAX_SIZE];
\r
727 if (instance_name == NULL)
\r
729 char exe_path[MAX_PATH];
\r
730 GetModuleFileName(NULL, exe_path, sizeof(exe_path));
\r
731 HashInstanceName(tmp, sizeof(tmp), exe_path);
\r
732 instance_name = tmp;
\r
735 hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, instance_name);
\r
736 if (hMutex != NULL)
\r
738 CloseHandle(hMutex);
\r
742 hMutex = CreateMutex(NULL, FALSE, instance_name);
\r
743 if (hMutex == NULL)
\r
745 CloseHandle(hMutex);
\r
749 ret = Win32MemoryAlloc(sizeof(WIN32MUTEX));
\r
750 ret->hMutex = hMutex;
\r
752 return (void *)ret;
\r
756 void Win32FreeSingleInstance(void *data)
\r
765 m = (WIN32MUTEX *)data;
\r
766 ReleaseMutex(m->hMutex);
\r
767 CloseHandle(m->hMutex);
\r
769 Win32MemoryFree(m);
\r
773 void Win32SetHighPriority()
\r
775 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
\r
779 void Win32RestorePriority()
\r
781 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
\r
785 char* Win32GetProductId()
\r
789 return CopyStr("--");
\r
792 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
\r
793 if (product_id == NULL)
\r
795 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
\r
801 // 現在サポートされている OS かどうか取得
\r
802 bool Win32IsSupportedOs()
\r
804 if (Win32GetOsType() == 0)
\r
807 "SoftEther UT-VPN doesn't support this Windows Operating System.\n"
\r
808 "SoftEther UT-VPN requires " SUPPORTED_WINDOWS_LIST ".\n\n"
\r
809 "Please contact your system administrator.", NULL);
\r
817 void Win32AlertW(wchar_t *msg, wchar_t *caption)
\r
825 if (caption == NULL)
\r
827 caption = L"SoftEther UT-VPN Kernel";
\r
830 s = GetCommandLineStr();
\r
832 if (SearchStr(s, "win9x_uninstall", 0) == INFINITE && SearchStr(s, "win9x_install", 0) == INFINITE)
\r
834 // Win9x サービスモードのアンインストール時には非表示とする
\r
835 MessageBoxW(NULL, msg, caption, MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);
\r
840 void Win32Alert(char *msg, char *caption)
\r
848 if (caption == NULL)
\r
850 caption = "SoftEther UT-VPN Kernel";
\r
853 s = GetCommandLineStr();
\r
855 if (SearchStr(s, "win9x_uninstall", 0) == INFINITE && SearchStr(s, "win9x_install", 0) == INFINITE)
\r
857 // Win9x サービスモードのアンインストール時には非表示とする
\r
858 MessageBox(NULL, msg, caption, MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);
\r
863 void Win32DebugAlert(char *msg)
\r
871 MessageBox(NULL, msg, "Debug", MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);
\r
875 void Win32GetOsInfo(OS_INFO *info)
\r
877 UINT type = Win32GetOsType();
\r
878 OSVERSIONINFOEX os;
\r
879 char tmp[MAX_SIZE];
\r
886 Zero(&os, sizeof(os));
\r
887 os.dwOSVersionInfoSize = sizeof(os);
\r
888 GetVersionEx((LPOSVERSIONINFOA)&os);
\r
890 info->OsType = Win32GetOsType();
\r
891 info->OsServicePack = os.wServicePackMajor;
\r
892 if (OS_IS_WINDOWS_NT(info->OsType))
\r
895 char *keyname = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
\r
896 info->OsSystemName = CopyStr("Windows NT");
\r
897 Format(tmp, sizeof(tmp), "Build %u", os.dwBuildNumber);
\r
898 if (s = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "CurrentType"))
\r
900 char str[MAX_SIZE];
\r
901 Format(str, sizeof(str), ", %s", s);
\r
902 StrCat(tmp, sizeof(tmp), str);
\r
905 if (os.wServicePackMajor != 0)
\r
907 char str[MAX_SIZE];
\r
908 Format(str, sizeof(str), ", Service Pack %u", os.wServicePackMajor);
\r
909 StrCat(tmp, sizeof(tmp), str);
\r
911 if (s = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "BuildLab"))
\r
913 char str[MAX_SIZE];
\r
914 Format(str, sizeof(str), " (%s)", s);
\r
915 StrCat(tmp, sizeof(tmp), str);
\r
918 info->OsVersion = CopyStr(tmp);
\r
919 info->KernelName = CopyStr("NTOS Kernel");
\r
920 Format(tmp, sizeof(tmp), "Build %u", os.dwBuildNumber);
\r
921 if (s = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "CurrentType"))
\r
923 char str[MAX_SIZE];
\r
924 Format(str, sizeof(str), " %s", s);
\r
925 StrCat(tmp, sizeof(tmp), str);
\r
928 info->KernelVersion = CopyStr(tmp);
\r
933 Zero(&os, sizeof(os));
\r
934 os.dwOSVersionInfoSize = sizeof(os);
\r
936 Format(tmp, sizeof(tmp), "Build %u %s", LOWORD(os.dwBuildNumber), os.szCSDVersion);
\r
938 info->OsVersion = CopyStr(tmp);
\r
939 info->OsSystemName = CopyStr("Windows");
\r
940 info->KernelName = CopyStr("Windows 9x Kernel");
\r
941 info->KernelVersion = CopyStr(tmp);
\r
944 info->OsProductName = CopyStr(OsTypeToStr(info->OsType));
\r
945 info->OsVendorName = CopyStr("Microsoft Corporation");
\r
948 // Windows NT かどうか取得
\r
952 Zero(&os, sizeof(os));
\r
953 os.dwOSVersionInfoSize = sizeof(os);
\r
955 if (GetVersionEx(&os) == FALSE)
\r
961 if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
\r
972 UINT Win32GetOsType()
\r
975 Zero(&os, sizeof(os));
\r
976 os.dwOSVersionInfoSize = sizeof(os);
\r
978 if (GetVersionEx(&os) == FALSE)
\r
984 if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
\r
987 if (os.dwMajorVersion == 4)
\r
989 if (os.dwMinorVersion == 0)
\r
991 return OSTYPE_WINDOWS_95;
\r
993 else if (os.dwMinorVersion == 10)
\r
995 return OSTYPE_WINDOWS_98;
\r
997 else if (os.dwMinorVersion == 90)
\r
999 return OSTYPE_WINDOWS_ME;
\r
1003 return OSTYPE_WINDOWS_UNKNOWN;
\r
1006 else if (os.dwMajorVersion >= 5)
\r
1008 return OSTYPE_WINDOWS_UNKNOWN;
\r
1011 else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
\r
1013 UINT sp = Win32GetSpVer(os.szCSDVersion);
\r
1014 if (os.dwMajorVersion == 4)
\r
1022 if (os.dwMajorVersion < 4)
\r
1029 OSVERSIONINFOEX os;
\r
1030 Zero(&os, sizeof(os));
\r
1031 os.dwOSVersionInfoSize = sizeof(os);
\r
1032 GetVersionEx((LPOSVERSIONINFOA)&os);
\r
1034 if (os.dwMajorVersion == 4)
\r
1037 if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)
\r
1039 if ((os.wSuiteMask & VER_SUITE_TERMINAL) || (os.wSuiteMask & VER_SUITE_SINGLEUSERTS))
\r
1041 return OSTYPE_WINDOWS_NT_4_TERMINAL_SERVER;
\r
1043 if (os.wSuiteMask & VER_SUITE_ENTERPRISE)
\r
1045 return OSTYPE_WINDOWS_NT_4_SERVER_ENTERPRISE;
\r
1047 if (os.wSuiteMask & VER_SUITE_BACKOFFICE)
\r
1049 return OSTYPE_WINDOWS_NT_4_BACKOFFICE;
\r
1051 if ((os.wSuiteMask & VER_SUITE_SMALLBUSINESS) || (os.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED))
\r
1053 return OSTYPE_WINDOWS_NT_4_SMS;
\r
1057 return OSTYPE_WINDOWS_NT_4_SERVER;
\r
1062 return OSTYPE_WINDOWS_NT_4_WORKSTATION;
\r
1065 else if (os.dwMajorVersion == 5)
\r
1067 // Windows 2000, XP, Server 2003
\r
1068 if (os.dwMinorVersion == 0)
\r
1071 if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)
\r
1074 if (os.wSuiteMask & VER_SUITE_DATACENTER)
\r
1076 return OSTYPE_WINDOWS_2000_DATACENTER_SERVER;
\r
1078 else if ((os.wSuiteMask & VER_SUITE_SMALLBUSINESS) || (os.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED))
\r
1080 return OSTYPE_WINDOWS_2000_SBS;
\r
1082 else if (os.wSuiteMask & VER_SUITE_BACKOFFICE)
\r
1084 return OSTYPE_WINDOWS_2000_BACKOFFICE;
\r
1086 else if (os.wSuiteMask & VER_SUITE_ENTERPRISE)
\r
1088 return OSTYPE_WINDOWS_2000_ADVANCED_SERVER;
\r
1092 return OSTYPE_WINDOWS_2000_SERVER;
\r
1098 return OSTYPE_WINDOWS_2000_PROFESSIONAL;
\r
1101 else if (os.dwMinorVersion == 1)
\r
1104 if (os.wSuiteMask & VER_SUITE_PERSONAL)
\r
1106 return OSTYPE_WINDOWS_XP_HOME;
\r
1110 return OSTYPE_WINDOWS_XP_PROFESSIONAL;
\r
1113 else if (os.dwMinorVersion == 2)
\r
1115 // Windows Server 2003
\r
1116 if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)
\r
1119 if (os.wSuiteMask & VER_SUITE_DATACENTER)
\r
1121 return OSTYPE_WINDOWS_2003_DATACENTER;
\r
1123 else if ((os.wSuiteMask & VER_SUITE_SMALLBUSINESS) || (os.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED))
\r
1125 return OSTYPE_WINDOWS_2003_SBS;
\r
1127 else if (os.wSuiteMask & VER_SUITE_BACKOFFICE)
\r
1129 return OSTYPE_WINDOWS_2003_BACKOFFICE;
\r
1131 else if (os.wSuiteMask & VER_SUITE_ENTERPRISE)
\r
1133 return OSTYPE_WINDOWS_2003_ENTERPRISE;
\r
1135 else if (os.wSuiteMask & VER_SUITE_BLADE)
\r
1137 return OSTYPE_WINDOWS_2003_WEB;
\r
1141 return OSTYPE_WINDOWS_2003_STANDARD;
\r
1146 // Client (Unknown XP?)
\r
1147 return OSTYPE_WINDOWS_XP_PROFESSIONAL;
\r
1152 // Windows Longhorn
\r
1153 if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)
\r
1155 return OSTYPE_WINDOWS_LONGHORN_SERVER;
\r
1159 return OSTYPE_WINDOWS_LONGHORN_PROFESSIONAL;
\r
1165 if (os.dwMajorVersion == 6 && os.dwMinorVersion == 0)
\r
1167 // Windows Vista, Server 2008
\r
1168 if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)
\r
1170 return OSTYPE_WINDOWS_LONGHORN_SERVER;
\r
1174 return OSTYPE_WINDOWS_LONGHORN_PROFESSIONAL;
\r
1177 else if (os.dwMajorVersion == 6 && os.dwMinorVersion == 1)
\r
1179 if (os.wProductType == VER_NT_WORKSTATION)
\r
1182 return OSTYPE_WINDOWS_7;
\r
1186 // Windows Server 2008 R2
\r
1187 return OSTYPE_WINDOWS_SERVER_2008_R2;
\r
1192 if (os.wProductType == VER_NT_WORKSTATION)
\r
1195 return OSTYPE_WINDOWS_8;
\r
1199 // Windows Server 8
\r
1200 return OSTYPE_WINDOWS_SERVER_2008_R2;
\r
1211 // 文字列から SP のバージョンを取得する
\r
1212 UINT Win32GetSpVer(char *str)
\r
1222 t = ParseToken(str, NULL);
\r
1229 for (i = 0;i < t->NumTokens;i++)
\r
1231 ret = ToInt(t->Token[i]);
\r
1244 bool Win32TerminateProcess(void *handle)
\r
1248 if (handle == NULL)
\r
1253 h = (HANDLE)handle;
\r
1255 TerminateProcess(h, 0);
\r
1261 void Win32CloseProcess(void *handle)
\r
1264 if (handle == NULL)
\r
1269 CloseHandle((HANDLE)handle);
\r
1272 // 指定されたプロセスが生きているかどうかチェック
\r
1273 bool Win32IsProcessAlive(void *handle)
\r
1277 if (handle == NULL)
\r
1282 h = (HANDLE)handle;
\r
1284 if (WaitForSingleObject(h, 0) == WAIT_OBJECT_0)
\r
1293 bool Win32WaitProcess(void *h, UINT timeout)
\r
1302 timeout = INFINITE;
\r
1305 if (WaitForSingleObject((HANDLE)h, timeout) == WAIT_TIMEOUT)
\r
1313 // プロセスの起動 (ハンドルを返す)
\r
1314 void *Win32RunExW(wchar_t *filename, wchar_t *arg, bool hide)
\r
1316 return Win32RunEx2W(filename, arg, hide, NULL);
\r
1318 void *Win32RunEx2W(wchar_t *filename, wchar_t *arg, bool hide, UINT *process_id)
\r
1320 return Win32RunEx3W(filename, arg, hide, process_id, false);
\r
1322 void *Win32RunEx3W(wchar_t *filename, wchar_t *arg, bool hide, UINT *process_id, bool disableWow)
\r
1324 STARTUPINFOW info;
\r
1325 PROCESS_INFORMATION ret;
\r
1326 wchar_t cmdline[MAX_SIZE];
\r
1327 wchar_t name[MAX_PATH];
\r
1330 if (filename == NULL)
\r
1335 if (IsNt() == false)
\r
1337 char *filename_a = CopyUniToStr(filename);
\r
1338 char *arg_a = CopyUniToStr(arg);
\r
1339 void *ret = Win32RunEx(filename_a, arg_a, hide);
\r
1347 UniStrCpy(name, sizeof(name), filename);
\r
1350 if (UniSearchStr(name, L"\"", 0) == INFINITE)
\r
1354 UniFormat(cmdline, sizeof(cmdline), L"%s", name);
\r
1358 UniFormat(cmdline, sizeof(cmdline), L"%s %s", name, arg);
\r
1365 UniFormat(cmdline, sizeof(cmdline), L"\"%s\"", name);
\r
1369 UniFormat(cmdline, sizeof(cmdline), L"\"%s\" %s", name, arg);
\r
1373 Zero(&info, sizeof(info));
\r
1374 Zero(&ret, sizeof(ret));
\r
1375 info.cb = sizeof(info);
\r
1376 info.dwFlags = STARTF_USESHOWWINDOW;
\r
1377 info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);
\r
1383 p = MsDisableWow64FileSystemRedirection();
\r
1386 if (CreateProcessW(NULL, cmdline, NULL, NULL, FALSE,
\r
1387 (hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,
\r
1388 NULL, NULL, &info, &ret) == FALSE)
\r
1392 MsRestoreWow64FileSystemRedirection(p);
\r
1399 MsRestoreWow64FileSystemRedirection(p);
\r
1402 if (process_id != NULL)
\r
1404 *process_id = ret.dwProcessId;
\r
1407 CloseHandle(ret.hThread);
\r
1408 return ret.hProcess;
\r
1410 void *Win32RunEx(char *filename, char *arg, bool hide)
\r
1412 return Win32RunEx2(filename, arg, hide, NULL);
\r
1414 void *Win32RunEx2(char *filename, char *arg, bool hide, UINT *process_id)
\r
1416 return Win32RunEx3(filename, arg, hide, process_id, false);
\r
1418 void *Win32RunEx3(char *filename, char *arg, bool hide, UINT *process_id, bool disableWow)
\r
1421 PROCESS_INFORMATION ret;
\r
1422 char cmdline[MAX_SIZE];
\r
1423 char name[MAX_PATH];
\r
1426 if (filename == NULL)
\r
1431 StrCpy(name, sizeof(name), filename);
\r
1434 if (SearchStr(name, "\"", 0) == INFINITE)
\r
1438 Format(cmdline, sizeof(cmdline), "%s", name);
\r
1442 Format(cmdline, sizeof(cmdline), "%s %s", name, arg);
\r
1449 Format(cmdline, sizeof(cmdline), "\"%s\"", name);
\r
1453 Format(cmdline, sizeof(cmdline), "\"%s\" %s", name, arg);
\r
1457 Zero(&info, sizeof(info));
\r
1458 Zero(&ret, sizeof(ret));
\r
1459 info.cb = sizeof(info);
\r
1460 info.dwFlags = STARTF_USESHOWWINDOW;
\r
1461 info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);
\r
1467 p = MsDisableWow64FileSystemRedirection();
\r
1470 if (CreateProcess(NULL, cmdline, NULL, NULL, FALSE,
\r
1471 (hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,
\r
1472 NULL, NULL, &info, &ret) == FALSE)
\r
1476 MsRestoreWow64FileSystemRedirection(p);
\r
1482 MsRestoreWow64FileSystemRedirection(p);
\r
1485 if (process_id != NULL)
\r
1487 *process_id = ret.dwProcessId;
\r
1490 CloseHandle(ret.hThread);
\r
1491 return ret.hProcess;
\r
1495 bool Win32RunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait)
\r
1497 STARTUPINFOW info;
\r
1498 PROCESS_INFORMATION ret;
\r
1499 wchar_t cmdline[MAX_SIZE];
\r
1500 wchar_t name[MAX_PATH];
\r
1502 if (filename == NULL)
\r
1507 if (IsNt() == false)
\r
1509 char *filename_a = CopyUniToStr(filename);
\r
1510 char *arg_a = CopyUniToStr(arg);
\r
1513 ret = Win32Run(filename_a, arg_a, hide, wait);
\r
1521 UniStrCpy(name, sizeof(name), filename);
\r
1524 if (UniSearchStr(name, L"\"", 0) == INFINITE)
\r
1528 UniFormat(cmdline, sizeof(cmdline), L"%s", name);
\r
1532 UniFormat(cmdline, sizeof(cmdline), L"%s %s", name, arg);
\r
1539 UniFormat(cmdline, sizeof(cmdline), L"\"%s\"", name);
\r
1543 UniFormat(cmdline, sizeof(cmdline), L"\"%s\" %s", name, arg);
\r
1547 Zero(&info, sizeof(info));
\r
1548 Zero(&ret, sizeof(ret));
\r
1549 info.cb = sizeof(info);
\r
1550 info.dwFlags = STARTF_USESHOWWINDOW;
\r
1551 info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);
\r
1555 if (CreateProcessW(NULL, cmdline, NULL, NULL, FALSE,
\r
1556 (hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,
\r
1557 NULL, NULL, &info, &ret) == FALSE)
\r
1564 WaitForSingleObject(ret.hProcess, INFINITE);
\r
1567 CloseHandle(ret.hThread);
\r
1568 CloseHandle(ret.hProcess);
\r
1572 bool Win32Run(char *filename, char *arg, bool hide, bool wait)
\r
1575 PROCESS_INFORMATION ret;
\r
1576 char cmdline[MAX_SIZE];
\r
1577 char name[MAX_PATH];
\r
1579 if (filename == NULL)
\r
1584 StrCpy(name, sizeof(name), filename);
\r
1587 if (SearchStr(name, "\"", 0) == INFINITE)
\r
1591 Format(cmdline, sizeof(cmdline), "%s", name);
\r
1595 Format(cmdline, sizeof(cmdline), "%s %s", name, arg);
\r
1602 Format(cmdline, sizeof(cmdline), "\"%s\"", name);
\r
1606 Format(cmdline, sizeof(cmdline), "\"%s\" %s", name, arg);
\r
1610 Zero(&info, sizeof(info));
\r
1611 Zero(&ret, sizeof(ret));
\r
1612 info.cb = sizeof(info);
\r
1613 info.dwFlags = STARTF_USESHOWWINDOW;
\r
1614 info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);
\r
1618 if (CreateProcess(NULL, cmdline, NULL, NULL, FALSE,
\r
1619 (hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,
\r
1620 NULL, NULL, &info, &ret) == FALSE)
\r
1627 WaitForSingleObject(ret.hProcess, INFINITE);
\r
1630 CloseHandle(ret.hThread);
\r
1631 CloseHandle(ret.hProcess);
\r
1637 UINT Win32ThreadId()
\r
1639 return GetCurrentThreadId();
\r
1643 bool Win32FileRenameW(wchar_t *old_name, wchar_t *new_name)
\r
1646 if (old_name == NULL || new_name == NULL)
\r
1651 if (IsNt() == false)
\r
1653 char *old_name_a = CopyUniToStr(old_name);
\r
1654 char *new_name_a = CopyUniToStr(new_name);
\r
1655 bool ret = Win32FileRename(old_name_a, new_name_a);
\r
1664 if (MoveFileW(old_name, new_name) == FALSE)
\r
1671 bool Win32FileRename(char *old_name, char *new_name)
\r
1674 if (old_name == NULL || new_name == NULL)
\r
1680 if (MoveFile(old_name, new_name) == FALSE)
\r
1688 // EXE ファイルが存在しているディレクトリ名を取得する
\r
1689 void Win32GetExeDirW(wchar_t *name, UINT size)
\r
1691 wchar_t exe_path[MAX_SIZE];
\r
1692 wchar_t exe_dir[MAX_SIZE];
\r
1699 if (IsNt() == false)
\r
1701 char name_a[MAX_PATH];
\r
1703 Win32GetExeDir(name_a, sizeof(name_a));
\r
1705 StrToUni(name, size, name_a);
\r
1711 GetModuleFileNameW(NULL, exe_path, sizeof(exe_path));
\r
1714 Win32GetDirFromPathW(exe_dir, sizeof(exe_dir), exe_path);
\r
1716 UniStrCpy(name, size, exe_dir);
\r
1718 void Win32GetExeDir(char *name, UINT size)
\r
1720 char exe_path[MAX_SIZE];
\r
1721 char exe_dir[MAX_SIZE];
\r
1729 GetModuleFileName(NULL, exe_path, sizeof(exe_path));
\r
1732 Win32GetDirFromPath(exe_dir, sizeof(exe_dir), exe_path);
\r
1734 StrCpy(name, size, exe_dir);
\r
1738 void Win32NukuEnW(wchar_t *dst, UINT size, wchar_t *src)
\r
1740 wchar_t str[MAX_SIZE];
\r
1744 UniStrCpy(str, sizeof(str), src);
\r
1748 UniStrCpy(str, sizeof(str), dst);
\r
1750 i = UniStrLen(str);
\r
1751 if (str[i - 1] == L'\\')
\r
1755 UniStrCpy(dst, size, str);
\r
1757 void Win32NukuEn(char *dst, UINT size, char *src)
\r
1759 char str[MAX_SIZE];
\r
1763 StrCpy(str, sizeof(str), src);
\r
1767 StrCpy(str, sizeof(str), dst);
\r
1770 if (str[i - 1] == '\\')
\r
1774 StrCpy(dst, size, str);
\r
1778 void Win32GetDirFromPathW(wchar_t *dst, UINT size, wchar_t *src)
\r
1780 wchar_t str[MAX_SIZE];
\r
1783 wchar_t tmp[MAX_SIZE];
\r
1787 UniStrCpy(str, sizeof(str), src);
\r
1791 UniStrCpy(str, sizeof(str), dst);
\r
1793 Win32NukuEnW(str, sizeof(str), NULL);
\r
1795 len = UniStrLen(str);
\r
1797 for (i = 0;i < len;i++)
\r
1805 UniStrCat(dst, size, tmp);
\r
1806 UniStrCat(dst, size, L"\\");
\r
1814 Win32NukuEnW(dst, size, NULL);
\r
1816 void Win32GetDirFromPath(char *dst, UINT size, char *src)
\r
1818 char str[MAX_SIZE];
\r
1821 char tmp[MAX_SIZE];
\r
1825 StrCpy(str, sizeof(str), src);
\r
1829 StrCpy(str, sizeof(str), dst);
\r
1831 Win32NukuEn(str, sizeof(str), NULL);
\r
1833 len = StrLen(str);
\r
1835 for (i = 0;i < len;i++)
\r
1843 StrCat(dst, size, tmp);
\r
1844 StrCat(dst, size, "\\");
\r
1852 Win32NukuEn(dst, size, NULL);
\r
1856 bool Win32DeleteDirW(wchar_t *name)
\r
1864 if (IsNt() == false)
\r
1866 char *name_a = CopyUniToStr(name);
\r
1867 bool ret = Win32DeleteDir(name_a);
\r
1874 if (RemoveDirectoryW(name) == FALSE)
\r
1880 bool Win32DeleteDir(char *name)
\r
1888 if (RemoveDirectory(name) == FALSE)
\r
1896 bool Win32MakeDirW(wchar_t *name)
\r
1904 if (IsNt() == false)
\r
1906 char *name_a = CopyUniToStr(name);
\r
1907 bool ret = Win32MakeDir(name_a);
\r
1914 if (CreateDirectoryW(name, NULL) == FALSE)
\r
1921 bool Win32MakeDir(char *name)
\r
1929 if (CreateDirectory(name, NULL) == FALSE)
\r
1938 bool Win32FileDeleteW(wchar_t *name)
\r
1946 if (IsNt() == false)
\r
1949 char *name_a = CopyUniToStr(name);
\r
1951 ret = Win32FileDelete(name_a);
\r
1958 if (DeleteFileW(name) == FALSE)
\r
1964 bool Win32FileDelete(char *name)
\r
1972 if (DeleteFile(name) == FALSE)
\r
1980 bool Win32FileSeek(void *pData, UINT mode, int offset)
\r
1985 if (pData == NULL)
\r
1989 if (mode != FILE_BEGIN && mode != FILE_END && mode != FILE_CURRENT)
\r
1994 p = (WIN32IO *)pData;
\r
1995 ret = SetFilePointer(p->hFile, (LONG)offset, NULL, mode);
\r
1996 if (ret == INVALID_SET_FILE_POINTER || ret == ERROR_NEGATIVE_SEEK)
\r
2004 UINT64 Win32FileSize(void *pData)
\r
2010 if (pData == NULL)
\r
2015 p = (WIN32IO *)pData;
\r
2017 ret = GetFileSize(p->hFile, &tmp);
\r
2018 if (ret == (DWORD)-1)
\r
2025 ret += (UINT64)tmp * 4294967296ULL;
\r
2032 bool Win32FileWrite(void *pData, void *buf, UINT size)
\r
2037 if (pData == NULL || buf == NULL || size == 0)
\r
2042 p = (WIN32IO *)pData;
\r
2043 if (WriteFile(p->hFile, buf, size, &write_size, NULL) == FALSE)
\r
2048 if (write_size != size)
\r
2057 bool Win32FileRead(void *pData, void *buf, UINT size)
\r
2062 if (pData == NULL || buf == NULL || size == 0)
\r
2067 p = (WIN32IO *)pData;
\r
2068 if (ReadFile(p->hFile, buf, size, &read_size, NULL) == FALSE)
\r
2073 if (read_size != size)
\r
2082 void Win32FileClose(void *pData, bool no_flush)
\r
2086 if (pData == NULL)
\r
2091 p = (WIN32IO *)pData;
\r
2092 if (p->WriteMode && no_flush == false)
\r
2094 FlushFileBuffers(p->hFile);
\r
2096 CloseHandle(p->hFile);
\r
2100 Win32MemoryFree(p);
\r
2104 void Win32FileFlush(void *pData)
\r
2108 if (pData == NULL)
\r
2113 p = (WIN32IO *)pData;
\r
2116 FlushFileBuffers(p->hFile);
\r
2121 void *Win32FileOpenW(wchar_t *name, bool write_mode, bool read_lock)
\r
2132 if (IsNt() == false)
\r
2135 char *name_a = CopyUniToStr(name);
\r
2137 ret = Win32FileOpen(name_a, write_mode, read_lock);
\r
2146 lock_mode = FILE_SHARE_READ;
\r
2150 if (read_lock == false)
\r
2152 lock_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
\r
2156 lock_mode = FILE_SHARE_READ;
\r
2161 h = CreateFileW(name,
\r
2162 (write_mode ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ),
\r
2164 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
\r
2165 if (h == INVALID_HANDLE_VALUE)
\r
2167 UINT ret = GetLastError();
\r
2173 p = Win32MemoryAlloc(sizeof(WIN32IO));
\r
2177 p->WriteMode = write_mode;
\r
2181 void *Win32FileOpen(char *name, bool write_mode, bool read_lock)
\r
2194 lock_mode = FILE_SHARE_READ;
\r
2198 if (read_lock == false)
\r
2200 lock_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
\r
2204 lock_mode = FILE_SHARE_READ;
\r
2209 h = CreateFile(name,
\r
2210 (write_mode ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ),
\r
2212 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
\r
2213 if (h == INVALID_HANDLE_VALUE)
\r
2215 UINT ret = GetLastError();
\r
2221 p = Win32MemoryAlloc(sizeof(WIN32IO));
\r
2225 p->WriteMode = write_mode;
\r
2231 void *Win32FileCreateW(wchar_t *name)
\r
2241 if (IsNt() == false)
\r
2244 char *name_a = CopyUniToStr(name);
\r
2246 ret = Win32FileCreate(name_a);
\r
2254 h = CreateFileW(name, GENERIC_READ | GENERIC_WRITE,
\r
2255 FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
\r
2257 if (h == INVALID_HANDLE_VALUE)
\r
2259 h = CreateFileW(name, GENERIC_READ | GENERIC_WRITE,
\r
2260 FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN,
\r
2262 if (h == INVALID_HANDLE_VALUE)
\r
2269 p = Win32MemoryAlloc(sizeof(WIN32IO));
\r
2273 p->WriteMode = true;
\r
2277 void *Win32FileCreate(char *name)
\r
2288 h = CreateFile(name, GENERIC_READ | GENERIC_WRITE,
\r
2289 FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
\r
2291 if (h == INVALID_HANDLE_VALUE)
\r
2293 h = CreateFile(name, GENERIC_READ | GENERIC_WRITE,
\r
2294 FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN,
\r
2296 if (h == INVALID_HANDLE_VALUE)
\r
2303 p = Win32MemoryAlloc(sizeof(WIN32IO));
\r
2307 p->WriteMode = true;
\r
2312 #define SIZE_OF_CALLSTACK_SYM 10000
\r
2313 #define CALLSTACK_DEPTH 12
\r
2316 CALLSTACK_DATA *Win32GetCallStack()
\r
2318 #ifndef WIN32_NO_DEBUG_HELP_DLL
\r
2319 DWORD current_eip32 = 0, current_esp32 = 0, current_ebp32 = 0;
\r
2320 UINT64 current_eip = 0, current_esp = 0, current_ebp = 0;
\r
2322 CALLSTACK_DATA *cs = NULL, *s;
\r
2332 // レジスタ取得 (32 bit)
\r
2335 mov current_esp32, esp
\r
2336 mov current_ebp32, ebp
\r
2339 current_eip32 = (DWORD)Win32GetCallStack;
\r
2341 current_eip = (UINT64)current_eip32;
\r
2342 current_esp = (UINT64)current_esp32;
\r
2343 current_ebp = (UINT64)current_ebp32;
\r
2345 // レジスタ取得 (64 bit)
\r
2346 Zero(&context, sizeof(context));
\r
2347 context.ContextFlags = CONTEXT_FULL;
\r
2348 RtlCaptureContext(&context);
\r
2351 Zero(&sf, sizeof(sf));
\r
2354 sf.AddrPC.Offset = current_eip;
\r
2355 sf.AddrStack.Offset = current_esp;
\r
2356 sf.AddrFrame.Offset = current_ebp;
\r
2358 sf.AddrPC.Offset = context.Rip;
\r
2359 sf.AddrStack.Offset = context.Rsp;
\r
2360 sf.AddrFrame.Offset = context.Rsp;
\r
2363 sf.AddrPC.Mode = AddrModeFlat;
\r
2364 sf.AddrStack.Mode = AddrModeFlat;
\r
2365 sf.AddrFrame.Mode = AddrModeFlat;
\r
2369 DWORD type = IMAGE_FILE_MACHINE_I386;
\r
2372 type = IMAGE_FILE_MACHINE_AMD64;
\r
2375 if ((depth++) >= CALLSTACK_DEPTH)
\r
2381 ret = StackWalk64(type,
\r
2382 hCurrentProcessHandle,
\r
2383 GetCurrentThread(),
\r
2385 NULL, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL);
\r
2387 ret = StackWalk64(type,
\r
2388 hCurrentProcessHandle,
\r
2389 GetCurrentThread(),
\r
2391 &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL);
\r
2393 if (ret == false || sf.AddrFrame.Offset == 0)
\r
2400 cs = OSMemoryAlloc(sizeof(CALLSTACK_DATA));
\r
2405 s->next = OSMemoryAlloc(sizeof(CALLSTACK_DATA));
\r
2408 s->symbol_cache = false;
\r
2410 s->offset = sf.AddrPC.Offset;
\r
2414 s->filename[0] = 0;
\r
2418 #else // WIN32_NO_DEBUG_HELP_DLL
\r
2420 #endif // WIN32_NO_DEBUG_HELP_DLL
\r
2423 // コールスタックからシンボル情報を取得
\r
2424 bool Win32GetCallStackSymbolInfo(CALLSTACK_DATA *s)
\r
2426 #ifdef WIN32_NO_DEBUG_HELP_DLL
\r
2428 #else // WIN32_NO_DEBUG_HELP_DLL
\r
2431 IMAGEHLP_SYMBOL64 *sym;
\r
2432 IMAGEHLP_LINE64 line;
\r
2433 char tmp[MAX_PATH];
\r
2440 if (s->symbol_cache)
\r
2445 sym = OSMemoryAlloc(SIZE_OF_CALLSTACK_SYM);
\r
2446 sym->SizeOfStruct = SIZE_OF_CALLSTACK_SYM;
\r
2447 sym->MaxNameLength = SIZE_OF_CALLSTACK_SYM - sizeof(IMAGEHLP_SYMBOL64);
\r
2449 if (SymGetSymFromAddr64(hCurrentProcessHandle, s->offset, &disp, sym))
\r
2452 s->name = OSMemoryAlloc((UINT)strlen(sym->Name) + 1);
\r
2453 lstrcpy(s->name, sym->Name);
\r
2461 Zero(&line, sizeof(line));
\r
2462 line.SizeOfStruct = sizeof(line);
\r
2463 if (SymGetLineFromAddr64(hCurrentProcessHandle, s->offset, &disp32, &line))
\r
2465 disp = (UINT64)disp32;
\r
2466 s->line = line.LineNumber;
\r
2467 lstrcpy(s->filename, line.FileName);
\r
2468 Win32GetDirFromPath(tmp, sizeof(tmp), s->filename);
\r
2469 len = lstrlen(tmp);
\r
2470 lstrcpy(tmp, &s->filename[len + 1]);
\r
2471 lstrcpy(s->filename, tmp);
\r
2476 s->filename[0] = 0;
\r
2479 OSMemoryFree(sym);
\r
2481 s->symbol_cache = true;
\r
2484 #endif // WIN32_NO_DEBUG_HELP_DLL
\r
2487 // デフォルトの Win32 スレッド
\r
2488 DWORD CALLBACK Win32DefaultThreadProc(void *param)
\r
2490 WIN32THREADSTARTUPINFO *info = (WIN32THREADSTARTUPINFO *)param;
\r
2497 Win32InitNewThread();
\r
2500 info->thread_proc(info->thread, info->param);
\r
2503 ReleaseThread(info->thread);
\r
2505 Win32MemoryFree(info);
\r
2507 FreeOpenSSLThreadState();
\r
2514 bool Win32WaitThread(THREAD *t)
\r
2522 w = (WIN32THREAD *)t->pData;
\r
2529 if (WaitForSingleObject(w->hThread, INFINITE) == WAIT_OBJECT_0)
\r
2531 // スレッドがシグナル状態になった
\r
2540 void Win32FreeThread(THREAD *t)
\r
2548 w = (WIN32THREAD *)t->pData;
\r
2555 CloseHandle(w->hThread);
\r
2558 Win32MemoryFree(t->pData);
\r
2563 bool Win32InitThread(THREAD *t)
\r
2568 WIN32THREADSTARTUPINFO *info;
\r
2574 if (t->thread_proc == NULL)
\r
2580 w = Win32MemoryAlloc(sizeof(WIN32THREAD));
\r
2583 info = Win32MemoryAlloc(sizeof(WIN32THREADSTARTUPINFO));
\r
2584 info->param = t->param;
\r
2585 info->thread_proc = t->thread_proc;
\r
2591 hThread = (HANDLE)_beginthreadex(NULL, 0, Win32DefaultThreadProc, info, 0, &thread_id);
\r
2592 if (hThread == NULL)
\r
2597 Win32MemoryFree(info);
\r
2598 Win32MemoryFree(w);
\r
2603 w->hThread = hThread;
\r
2604 w->thread_id = thread_id;
\r
2609 // Win32 用ライブラリの初期化
\r
2612 INITCOMMONCONTROLSEX c;
\r
2615 // Windows NT かどうか取得する
\r
2616 Zero(&os, sizeof(os));
\r
2617 os.dwOSVersionInfoSize = sizeof(os);
\r
2618 GetVersionEx(&os);
\r
2620 if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
\r
2623 win32_is_nt = true;
\r
2628 win32_is_nt = false;
\r
2632 if (hstdout == INVALID_HANDLE_VALUE)
\r
2634 hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
\r
2638 if (hstdin == INVALID_HANDLE_VALUE)
\r
2640 hstdin = GetStdHandle(STD_INPUT_HANDLE);
\r
2643 Win32InitNewThread();
\r
2645 CoInitialize(NULL);
\r
2647 InitializeCriticalSection(&fasttick_lock);
\r
2649 #ifdef WIN32_USE_HEAP_API_FOR_MEMORY
\r
2650 use_heap_api = true;
\r
2651 #else // WIN32_USE_HEAP_API_FOR_MEMORY
\r
2652 use_heap_api = false;
\r
2653 #endif // WIN32_USE_HEAP_API_FOR_MEMORY
\r
2655 if (MayaquaIsDotNetMode())
\r
2657 // .NET API 内からヒープ関係の API を呼び出すとクラッシュする
\r
2658 use_heap_api = false;
\r
2661 if (IsNt() == false)
\r
2663 // Win9x ではヒープ関係の API は使用しない
\r
2664 use_heap_api = false;
\r
2669 heap_handle = HeapCreate(0, 0, 0);
\r
2673 hCurrentProcessHandle = GetCurrentProcess();
\r
2676 // Win32InitCurrentDir(); /* 行わない */
\r
2681 #ifndef WIN32_NO_DEBUG_HELP_DLL
\r
2682 SymInitialize(hCurrentProcessHandle, NULL, TRUE);
\r
2683 #endif // WIN32_NO_DEBUG_HELP_DLL
\r
2686 // Common Control の初期化
\r
2687 Zero(&c, sizeof(INITCOMMONCONTROLSEX));
\r
2688 c.dwSize = sizeof(INITCOMMONCONTROLSEX);
\r
2689 c.dwICC = ICC_ANIMATE_CLASS | ICC_BAR_CLASSES | ICC_COOL_CLASSES |
\r
2690 ICC_DATE_CLASSES | ICC_HOTKEY_CLASS | ICC_INTERNET_CLASSES |
\r
2691 ICC_LISTVIEW_CLASSES | ICC_NATIVEFNTCTL_CLASS |
\r
2692 ICC_PAGESCROLLER_CLASS | ICC_PROGRESS_CLASS |
\r
2693 ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS | ICC_USEREX_CLASSES |
\r
2694 ICC_WIN95_CLASSES;
\r
2695 InitCommonControlsEx(&c);
\r
2698 // Win32 用ライブラリの解放
\r
2704 #ifndef WIN32_NO_DEBUG_HELP_DLL
\r
2705 SymCleanup(hCurrentProcessHandle);
\r
2706 #endif // WIN32_NO_DEBUG_HELP_DLL
\r
2711 HeapDestroy(heap_handle);
\r
2712 heap_handle = NULL;
\r
2717 DeleteCriticalSection(&fasttick_lock);
\r
2721 void *Win32MemoryAlloc(UINT size)
\r
2725 return HeapAlloc(heap_handle, 0, size);
\r
2729 return malloc(size);
\r
2734 void *Win32MemoryReAlloc(void *addr, UINT size)
\r
2738 return HeapReAlloc(heap_handle, 0, addr, size);
\r
2742 return realloc(addr, size);
\r
2747 void Win32MemoryFree(void *addr)
\r
2751 HeapFree(heap_handle, 0, addr);
\r
2760 UINT Win32GetTick()
\r
2762 return (UINT)timeGetTime();
\r
2766 void Win32GetSystemTime(SYSTEMTIME *system_time)
\r
2769 GetSystemTime(system_time);
\r
2772 // 32bit 整数のインクリメント
\r
2773 void Win32Inc32(UINT *value)
\r
2775 InterlockedIncrement(value);
\r
2778 // 32bit 整数のデクリメント
\r
2779 void Win32Dec32(UINT *value)
\r
2781 InterlockedDecrement(value);
\r
2785 void Win32Sleep(UINT time)
\r
2791 LOCK *Win32NewLock()
\r
2794 LOCK *lock = Win32MemoryAlloc(sizeof(LOCK));
\r
2797 CRITICAL_SECTION *critical_section = Win32MemoryAlloc(sizeof(CRITICAL_SECTION));
\r
2799 if (lock == NULL || critical_section == NULL)
\r
2801 Win32MemoryFree(lock);
\r
2802 Win32MemoryFree(critical_section);
\r
2807 InitializeCriticalSection(critical_section);
\r
2809 lock->pData = (void *)critical_section;
\r
2810 lock->Ready = true;
\r
2816 bool Win32Lock(LOCK *lock)
\r
2818 CRITICAL_SECTION *critical_section;
\r
2819 if (lock->Ready == false)
\r
2826 critical_section = (CRITICAL_SECTION *)lock->pData;
\r
2827 EnterCriticalSection(critical_section);
\r
2833 void Win32Unlock(LOCK *lock)
\r
2835 Win32UnlockEx(lock, false);
\r
2837 void Win32UnlockEx(LOCK *lock, bool inner)
\r
2839 CRITICAL_SECTION *critical_section;
\r
2840 if (lock->Ready == false && inner == false)
\r
2846 // クリティカルセクションから出る
\r
2847 critical_section = (CRITICAL_SECTION *)lock->pData;
\r
2848 LeaveCriticalSection(critical_section);
\r
2852 void Win32DeleteLock(LOCK *lock)
\r
2854 CRITICAL_SECTION *critical_section;
\r
2855 // Ready フラグを安全に解除する
\r
2857 lock->Ready = false;
\r
2858 Win32UnlockEx(lock, true);
\r
2861 critical_section = (CRITICAL_SECTION *)lock->pData;
\r
2862 DeleteCriticalSection(critical_section);
\r
2865 Win32MemoryFree(critical_section);
\r
2866 Win32MemoryFree(lock);
\r
2870 void Win32InitEvent(EVENT *event)
\r
2873 HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
\r
2875 event->pData = hEvent;
\r
2879 void Win32SetEvent(EVENT *event)
\r
2881 HANDLE hEvent = (HANDLE)event->pData;
\r
2882 if (hEvent == NULL)
\r
2891 void Win32ResetEvent(EVENT *event)
\r
2893 HANDLE hEvent = (HANDLE)event->pData;
\r
2894 if (hEvent == NULL)
\r
2899 ResetEvent(hEvent);
\r
2903 bool Win32WaitEvent(EVENT *event, UINT timeout)
\r
2905 HANDLE hEvent = (HANDLE)event->pData;
\r
2907 if (hEvent == NULL)
\r
2913 ret = WaitForSingleObject(hEvent, timeout);
\r
2914 if (ret == WAIT_TIMEOUT)
\r
2927 void Win32FreeEvent(EVENT *event)
\r
2929 HANDLE hEvent = (HANDLE)event->pData;
\r
2930 if (hEvent == NULL)
\r
2935 CloseHandle(hEvent);
\r
2938 // Win32 専用の高速な 64 bit Tick 取得関数
\r
2939 UINT64 Win32FastTick64()
\r
2941 static UINT last_tick = 0;
\r
2942 static UINT counter = 0;
\r
2946 EnterCriticalSection(&fasttick_lock);
\r
2948 // 現在の tick 値を取得する
\r
2949 tick = Win32GetTick();
\r
2951 if (last_tick > tick)
\r
2953 // 前回取得した tick 値のほうが今回取得した値よりも大きい場合
\r
2954 // カウンタが 1 回りしたと考えることができる
\r
2961 ret = (UINT64)tick + (UINT64)counter * 4294967296ULL;
\r
2963 LeaveCriticalSection(&fasttick_lock);
\r
2965 if (start_tick == 0)
\r
2972 ret -= start_tick;
\r
2978 // 文字列をコンソールから読み込む
\r
2979 bool Win32InputW(wchar_t *str, UINT size)
\r
2989 size = 0x7fffffff;
\r
2992 if (str == NULL || size <= sizeof(wchar_t))
\r
2999 return Win32InputFromFileW(NULL, 0);
\r
3004 DWORD read_size = 0;
\r
3006 if (ReadConsoleW(hstdin, str, (size - sizeof(wchar_t)), &read_size, NULL))
\r
3008 str[read_size] = 0;
\r
3016 ret = Win32InputFromFileW(str, size);
\r
3021 DWORD read_size = 0;
\r
3022 UINT a_size = size / sizeof(wchar_t) + 16;
\r
3025 a = ZeroMalloc(a_size);
\r
3027 if (ReadConsoleA(hstdin, a, a_size - 1, &read_size, NULL))
\r
3031 StrToUni(str, size, a);
\r
3039 ret = Win32InputFromFileW(str, size);
\r
3048 bool Win32InputFromFileW(wchar_t *str, UINT size)
\r
3053 wchar_t tmp[MAX_SIZE];
\r
3054 Win32InputFromFileW(tmp, sizeof(tmp));
\r
3058 a = Win32InputFromFileLineA();
\r
3061 UniStrCpy(str, size, L"");
\r
3065 UtfToUni(str, size, a);
\r
3073 char *Win32InputFromFileLineA()
\r
3075 BUF *b = NewBuf();
\r
3083 UINT read_size = 0;
\r
3085 if (ReadFile(hstdin, &c, 1, &read_size, NULL) == false)
\r
3090 if (read_size != 1)
\r
3096 WriteBuf(b, &c, 1);
\r
3104 WriteBuf(b, &zero, 1);
\r
3108 ret = CopyStr(b->Buf);
\r
3116 // 文字列をコンソールにプリントする
\r
3117 void Win32PrintW(wchar_t *str)
\r
3119 DWORD write_size = 0;
\r
3128 if (WriteConsoleW(hstdout, str, UniStrLen(str), &write_size, NULL) == false)
\r
3130 Win32PrintToFileW(str);
\r
3135 char *ansi_str = CopyUniToStr(str);
\r
3137 if (WriteConsoleA(hstdout, ansi_str, StrLen(ansi_str), &write_size, NULL) == false)
\r
3139 Win32PrintToFileW(str);
\r
3145 void Win32PrintToFileW(wchar_t *str)
\r
3155 utf = CopyUniToUtf(str);
\r
3157 WriteFile(hstdout, utf, StrLen(utf), &size, NULL);
\r