* tar xzf utvpn-src-unix-v101-7101-public-2010.06.27.tar.gz
[lab.git] / utvpn / utvpn-unix-v101-7101-public / src / Mayaqua / Win32.c
1 // SoftEther UT-VPN SourceCode\r
2 // \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
7 // \r
8 // http://utvpn.tsukuba.ac.jp/\r
9 // \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
13 // \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
18 // \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
22 // \r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。\r
28 // \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
32 // ホストされています。\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、\r
34 // および、試験または研究のために利用が行われることを想定して配布\r
35 // しています。\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に\r
37 // あります。\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース\r
42 // に組み込みさせていただきます。\r
43 // \r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。\r
46 // \r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意\r
51 // ください。\r
52 // \r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、\r
58 // 公益保護にご協力いただきますようお願い申し上げます。\r
59 // \r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客\r
62 // を保護するための努力を行います。\r
63 // \r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/\r
65 // 日本国内の脆弱性情報届出受付公的機関:\r
66 //         独立行政法人 情報処理推進機構\r
67 //         http://www.ipa.go.jp/security/vuln/report/\r
68 // \r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/\r
71 \r
72 // -----------------------------------------------\r
73 // [ChangeLog]\r
74 // 2010.05.20\r
75 //  新規リリース by SoftEther\r
76 // -----------------------------------------------\r
77 \r
78 // Win32.c\r
79 // Microsoft Windows 依存コード\r
80 \r
81 #ifdef  WIN32\r
82 \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
90 #include <stdio.h>\r
91 #include <stdlib.h>\r
92 #include <string.h>\r
93 #include <wchar.h>\r
94 #include <stdarg.h>\r
95 #include <time.h>\r
96 #include <errno.h>\r
97 #include <Mayaqua/Mayaqua.h>\r
98 \r
99 static HANDLE heap_handle = NULL;\r
100 static HANDLE hstdout = INVALID_HANDLE_VALUE;\r
101 static HANDLE hstdin = INVALID_HANDLE_VALUE;\r
102 \r
103 // Win32 用スレッドデータ\r
104 typedef struct WIN32THREAD\r
105 {\r
106         HANDLE hThread;\r
107         DWORD thread_id;\r
108 } WIN32THREAD;\r
109 \r
110 // Win32 用スレッド起動情報\r
111 typedef struct WIN32THREADSTARTUPINFO\r
112 {\r
113         THREAD_PROC *thread_proc;\r
114         void *param;\r
115         THREAD *thread;\r
116 } WIN32THREADSTARTUPINFO;\r
117 \r
118 // Win32 用関数プロトタイプ\r
119 DWORD CALLBACK Win32DefaultThreadProc(void *param);\r
120 \r
121 // 現在のプロセスハンドル\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
127 \r
128 // Win32 用ファイル I/O データ\r
129 typedef struct WIN32IO\r
130 {\r
131         HANDLE hFile;\r
132         bool WriteMode;\r
133 } WIN32IO;\r
134 \r
135 // Win32 用ミューテックスデータ\r
136 typedef struct WIN32MUTEX\r
137 {\r
138         HANDLE hMutex;\r
139 } WIN32MUTEX;\r
140 \r
141 // ディスパッチテーブルの作成\r
142 OS_DISPATCH_TABLE *Win32GetDispatchTable()\r
143 {\r
144         static OS_DISPATCH_TABLE t =\r
145         {\r
146                 Win32Init,\r
147                 Win32Free,\r
148                 Win32MemoryAlloc,\r
149                 Win32MemoryReAlloc,\r
150                 Win32MemoryFree,\r
151                 Win32GetTick,\r
152                 Win32GetSystemTime,\r
153                 Win32Inc32,\r
154                 Win32Dec32,\r
155                 Win32Sleep,\r
156                 Win32NewLock,\r
157                 Win32Lock,\r
158                 Win32Unlock,\r
159                 Win32DeleteLock,\r
160                 Win32InitEvent,\r
161                 Win32SetEvent,\r
162                 Win32ResetEvent,\r
163                 Win32WaitEvent,\r
164                 Win32FreeEvent,\r
165                 Win32WaitThread,\r
166                 Win32FreeThread,\r
167                 Win32InitThread,\r
168                 Win32ThreadId,\r
169                 Win32FileOpen,\r
170                 Win32FileOpenW,\r
171                 Win32FileCreate,\r
172                 Win32FileCreateW,\r
173                 Win32FileWrite,\r
174                 Win32FileRead,\r
175                 Win32FileClose,\r
176                 Win32FileFlush,\r
177                 Win32FileSize,\r
178                 Win32FileSeek,\r
179                 Win32FileDelete,\r
180                 Win32FileDeleteW,\r
181                 Win32MakeDir,\r
182                 Win32MakeDirW,\r
183                 Win32DeleteDir,\r
184                 Win32DeleteDirW,\r
185                 Win32GetCallStack,\r
186                 Win32GetCallStackSymbolInfo,\r
187                 Win32FileRename,\r
188                 Win32FileRenameW,\r
189                 Win32Run,\r
190                 Win32RunW,\r
191                 Win32IsSupportedOs,\r
192                 Win32GetOsInfo,\r
193                 Win32Alert,\r
194                 Win32AlertW,\r
195                 Win32GetProductId,\r
196                 Win32SetHighPriority,\r
197                 Win32RestorePriority,\r
198                 Win32NewSingleInstance,\r
199                 Win32FreeSingleInstance,\r
200                 Win32GetMemInfo,\r
201                 Win32Yield,\r
202         };\r
203 \r
204         return &t;\r
205 }\r
206 \r
207 // 新しいスレッド用の初期化関数\r
208 void Win32InitNewThread()\r
209 {\r
210         static HINSTANCE hDll = NULL;\r
211         static bool (WINAPI *_SetThreadLocale)(LCID) = NULL;\r
212 \r
213         if (hDll == NULL)\r
214         {\r
215                 hDll = LoadLibrary("kernel32.dll");\r
216 \r
217                 _SetThreadLocale =\r
218                         (bool (__stdcall *)(LCID))\r
219                         GetProcAddress(hDll, "SetThreadLocale");\r
220         }\r
221 \r
222         if (_SetThreadLocale != NULL)\r
223         {\r
224                 _SetThreadLocale(LOCALE_USER_DEFAULT);\r
225         }\r
226 }\r
227 \r
228 // フォルダの圧縮フラグを設定する\r
229 bool Win32SetFolderCompressW(wchar_t *path, bool compressed)\r
230 {\r
231         HANDLE h;\r
232         UINT retsize = 0;\r
233         USHORT flag;\r
234         wchar_t tmp[MAX_PATH];\r
235         // 引数チェック\r
236         if (path == NULL)\r
237         {\r
238                 return false;\r
239         }\r
240 \r
241         if (IsNt() == false)\r
242         {\r
243                 char *path_a = CopyUniToStr(path);\r
244                 bool ret = Win32SetFolderCompress(path_a, compressed);\r
245 \r
246                 Free(path_a);\r
247 \r
248                 return ret;\r
249         }\r
250 \r
251         InnerFilePathW(tmp, sizeof(tmp), path);\r
252 \r
253         // フォルダを開く\r
254         h = CreateFileW(tmp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);\r
255 \r
256         if (h == INVALID_HANDLE_VALUE)\r
257         {\r
258                 return false;\r
259         }\r
260 \r
261         flag = compressed ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE;\r
262 \r
263         if (DeviceIoControl(h, FSCTL_SET_COMPRESSION, &flag, sizeof(USHORT),\r
264                 NULL, 0, &retsize, NULL) == false)\r
265         {\r
266                 return false;\r
267         }\r
268 \r
269         CloseHandle(h);\r
270 \r
271         return true;\r
272 }\r
273 bool Win32SetFolderCompress(char *path, bool compressed)\r
274 {\r
275         HANDLE h;\r
276         UINT retsize = 0;\r
277         USHORT flag;\r
278         char tmp[MAX_PATH];\r
279         // 引数チェック\r
280         if (path == NULL)\r
281         {\r
282                 return false;\r
283         }\r
284 \r
285         InnerFilePath(tmp, sizeof(tmp), path);\r
286 \r
287         // フォルダを開く\r
288         h = CreateFile(tmp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);\r
289 \r
290         if (h == INVALID_HANDLE_VALUE)\r
291         {\r
292                 return false;\r
293         }\r
294 \r
295         flag = compressed ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE;\r
296 \r
297         if (DeviceIoControl(h, FSCTL_SET_COMPRESSION, &flag, sizeof(USHORT),\r
298                 NULL, 0, &retsize, NULL) == false)\r
299         {\r
300                 return false;\r
301         }\r
302 \r
303         CloseHandle(h);\r
304 \r
305         return true;\r
306 }\r
307 \r
308 // ディスクの空き容量を取得する\r
309 bool Win32GetDiskFreeW(wchar_t *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)\r
310 {\r
311         wchar_t tmp[MAX_SIZE];\r
312         UINT count = 0;\r
313         UINT i, n, len;\r
314         ULARGE_INTEGER v1, v2, v3;\r
315         bool ret = false;\r
316         // 引数チェック\r
317         if (path == NULL)\r
318         {\r
319                 return false;\r
320         }\r
321 \r
322         if (IsNt() == false)\r
323         {\r
324                 bool ret;\r
325                 char *path_a = CopyUniToStr(path);\r
326 \r
327                 ret = Win32GetDiskFree(path_a, free_size, used_size, total_size);\r
328 \r
329                 Free(path_a);\r
330 \r
331                 return ret;\r
332         }\r
333 \r
334         Zero(&v1, sizeof(v1));\r
335         Zero(&v2, sizeof(v2));\r
336         Zero(&v3, sizeof(v3));\r
337 \r
338         NormalizePathW(tmp, sizeof(tmp), path);\r
339 \r
340         // ディレクトリ名を取得\r
341         if (UniStartWith(path, L"\\\\"))\r
342         {\r
343                 count = 4;\r
344         }\r
345         else\r
346         {\r
347                 count = 1;\r
348         }\r
349 \r
350         len = UniStrLen(tmp);\r
351         n = 0;\r
352         for (i = 0;i < len;i++)\r
353         {\r
354                 if (tmp[i] == L'\\')\r
355                 {\r
356                         n++;\r
357                         if (n >= count)\r
358                         {\r
359                                 tmp[i + 1] = 0;\r
360                                 break;\r
361                         }\r
362                 }\r
363         }\r
364 \r
365         if (GetDiskFreeSpaceExW(tmp, &v1, &v2, &v3))\r
366         {\r
367                 ret = true;\r
368         }\r
369 \r
370         if (free_size != NULL)\r
371         {\r
372                 *free_size = v1.QuadPart;\r
373         }\r
374 \r
375         if (total_size != NULL)\r
376         {\r
377                 *total_size = v2.QuadPart;\r
378         }\r
379 \r
380         if (used_size != NULL)\r
381         {\r
382                 *used_size = v2.QuadPart - v1.QuadPart;\r
383         }\r
384 \r
385         return ret;\r
386 }\r
387 bool Win32GetDiskFree(char *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)\r
388 {\r
389         char tmp[MAX_SIZE];\r
390         UINT count = 0;\r
391         UINT i, n, len;\r
392         ULARGE_INTEGER v1, v2, v3;\r
393         bool ret = false;\r
394         // 引数チェック\r
395         if (path == NULL)\r
396         {\r
397                 return false;\r
398         }\r
399 \r
400         Zero(&v1, sizeof(v1));\r
401         Zero(&v2, sizeof(v2));\r
402         Zero(&v3, sizeof(v3));\r
403 \r
404         NormalizePath(tmp, sizeof(tmp), path);\r
405 \r
406         // ディレクトリ名を取得\r
407         if (StartWith(path, "\\\\"))\r
408         {\r
409                 count = 4;\r
410         }\r
411         else\r
412         {\r
413                 count = 1;\r
414         }\r
415 \r
416         len = StrLen(tmp);\r
417         n = 0;\r
418         for (i = 0;i < len;i++)\r
419         {\r
420                 if (tmp[i] == '\\')\r
421                 {\r
422                         n++;\r
423                         if (n >= count)\r
424                         {\r
425                                 tmp[i + 1] = 0;\r
426                                 break;\r
427                         }\r
428                 }\r
429         }\r
430 \r
431         if (GetDiskFreeSpaceEx(tmp, &v1, &v2, &v3))\r
432         {\r
433                 ret = true;\r
434         }\r
435 \r
436         if (free_size != NULL)\r
437         {\r
438                 *free_size = v1.QuadPart;\r
439         }\r
440 \r
441         if (total_size != NULL)\r
442         {\r
443                 *total_size = v2.QuadPart;\r
444         }\r
445 \r
446         if (used_size != NULL)\r
447         {\r
448                 *used_size = v2.QuadPart - v1.QuadPart;\r
449         }\r
450 \r
451         return ret;\r
452 }\r
453 \r
454 // ディレクトリの列挙\r
455 DIRLIST *Win32EnumDirEx(char *dirname, COMPARE *compare)\r
456 {\r
457         DIRLIST *ret;\r
458         wchar_t *dirname_w = CopyStrToUni(dirname);\r
459 \r
460         ret = Win32EnumDirExW(dirname_w, compare);\r
461 \r
462         Free(dirname_w);\r
463 \r
464         return ret;\r
465 }\r
466 DIRLIST *Win32EnumDirExW(wchar_t *dirname, COMPARE *compare)\r
467 {\r
468         WIN32_FIND_DATAA data_a;\r
469         WIN32_FIND_DATAW data_w;\r
470         HANDLE h;\r
471         wchar_t tmp[MAX_PATH];\r
472         wchar_t tmp2[MAX_PATH];\r
473         wchar_t dirname2[MAX_PATH];\r
474         LIST *o;\r
475         DIRLIST *d;\r
476 \r
477         UniStrCpy(tmp2, sizeof(tmp2), dirname);\r
478 \r
479         if (UniStrLen(tmp2) >= 1 && tmp[UniStrLen(tmp2) - 1] == L'\\')\r
480         {\r
481                 tmp2[UniStrLen(tmp2) - 1] = 0;\r
482         }\r
483 \r
484         UniFormat(tmp, sizeof(tmp), L"%s\\*.*", tmp2);\r
485         NormalizePathW(tmp, sizeof(tmp), tmp);\r
486         NormalizePathW(dirname2, sizeof(dirname2), tmp2);\r
487 \r
488         o = NewListFast(compare);\r
489 \r
490         Zero(&data_a, sizeof(data_a));\r
491         Zero(&data_w, sizeof(data_w));\r
492 \r
493         if (IsNt())\r
494         {\r
495                 h = FindFirstFileW(tmp, &data_w);\r
496         }\r
497         else\r
498         {\r
499                 char *tmp_a = CopyUniToStr(tmp);\r
500 \r
501                 h = FindFirstFileA(tmp_a, &data_a);\r
502 \r
503                 Free(tmp_a);\r
504         }\r
505 \r
506         if (h != INVALID_HANDLE_VALUE)\r
507         {\r
508                 bool b = true;\r
509 \r
510                 do\r
511                 {\r
512                         if (IsNt() == false)\r
513                         {\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
521                         }\r
522 \r
523                         if (UniStrCmpi(data_w.cFileName, L"..") != 0 &&\r
524                                 UniStrCmpi(data_w.cFileName, L".") != 0)\r
525                         {\r
526                                 DIRENT *f = ZeroMalloc(sizeof(DIRENT));\r
527                                 SYSTEMTIME t1, t2;\r
528                                 wchar_t fullpath[MAX_SIZE];\r
529                                 bool ok = false;\r
530 \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
534 \r
535                                 CombinePathW(fullpath, sizeof(fullpath), dirname2, f->FileNameW);\r
536 \r
537                                 // ファイル情報の取得を試行する\r
538                                 if (MsIsNt())\r
539                                 {\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
543 \r
544                                         if (h != INVALID_HANDLE_VALUE)\r
545                                         {\r
546                                                 BY_HANDLE_FILE_INFORMATION info;\r
547 \r
548                                                 Zero(&info, sizeof(info));\r
549 \r
550                                                 if (MsGetFileInformation(h, &info))\r
551                                                 {\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
558 \r
559                                                         if (f->Folder == false)\r
560                                                         {\r
561                                                                 f->FileSize = ((UINT64)info.nFileSizeHigh * (UINT64)((UINT64)MAXDWORD + (UINT64)1)) + (UINT64)info.nFileSizeLow;\r
562                                                         }\r
563 \r
564                                                         ok = true;\r
565                                                 }\r
566 \r
567                                                 CloseHandle(h);\r
568                                         }\r
569                                 }\r
570 \r
571                                 if (ok == false)\r
572                                 {\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
579 \r
580                                         if (f->Folder == false)\r
581                                         {\r
582                                                 f->FileSize = ((UINT64)data_w.nFileSizeHigh * (UINT64)((UINT64)MAXDWORD + (UINT64)1)) + (UINT64)data_w.nFileSizeLow;\r
583                                         }\r
584                                 }\r
585 \r
586                                 Add(o, f);\r
587                         }\r
588 \r
589                         Zero(&data_w, sizeof(data_w));\r
590                         Zero(&data_a, sizeof(data_a));\r
591 \r
592                         if (IsNt())\r
593                         {\r
594                                 b = FindNextFileW(h, &data_w);\r
595                         }\r
596                         else\r
597                         {\r
598                                 b = FindNextFileA(h, &data_a);\r
599                         }\r
600                 }\r
601                 while (b);\r
602 \r
603                 FindClose(h);\r
604         }\r
605 \r
606         Sort(o);\r
607 \r
608         d = ZeroMalloc(sizeof(DIRLIST));\r
609         d->NumFiles = LIST_NUM(o);\r
610         d->File = ToArray(o);\r
611 \r
612         ReleaseList(o);\r
613 \r
614         return d;\r
615 }\r
616 \r
617 // EXE ファイル名を取得\r
618 void Win32GetExeNameW(wchar_t *name, UINT size)\r
619 {\r
620         // 引数チェック\r
621         if (name == NULL)\r
622         {\r
623                 return;\r
624         }\r
625 \r
626         if (IsNt() == false)\r
627         {\r
628                 char name_a[MAX_PATH];\r
629 \r
630                 Win32GetExeName(name_a, sizeof(name_a));\r
631 \r
632                 StrToUni(name, size, name_a);\r
633 \r
634                 return;\r
635         }\r
636 \r
637         UniStrCpy(name, size, L"");\r
638 \r
639         GetModuleFileNameW(NULL, name, size);\r
640 }\r
641 void Win32GetExeName(char *name, UINT size)\r
642 {\r
643         // 引数チェック\r
644         if (name == NULL)\r
645         {\r
646                 return;\r
647         }\r
648 \r
649         StrCpy(name, size, "");\r
650 \r
651         GetModuleFileName(NULL, name, size);\r
652 }\r
653 \r
654 // 現在のディレクトリの取得\r
655 void Win32GetCurrentDirW(wchar_t *dir, UINT size)\r
656 {\r
657         // 引数チェック\r
658         if (dir == NULL)\r
659         {\r
660                 return;\r
661         }\r
662 \r
663         if (IsNt() == false)\r
664         {\r
665                 char dir_a[MAX_PATH];\r
666 \r
667                 Win32GetCurrentDir(dir_a, sizeof(dir_a));\r
668 \r
669                 StrToUni(dir, size, dir_a);\r
670 \r
671                 return;\r
672         }\r
673 \r
674         GetCurrentDirectoryW(size, dir);\r
675 }\r
676 void Win32GetCurrentDir(char *dir, UINT size)\r
677 {\r
678         // 引数チェック\r
679         if (dir == NULL)\r
680         {\r
681                 return;\r
682         }\r
683 \r
684         GetCurrentDirectory(size, dir);\r
685 }\r
686 \r
687 // イールド\r
688 void Win32Yield()\r
689 {\r
690         Sleep(0);\r
691 }\r
692 \r
693 // メモリ情報の取得\r
694 void Win32GetMemInfo(MEMINFO *info)\r
695 {\r
696         MEMORYSTATUS st;\r
697         // 引数チェック\r
698         if (info == NULL)\r
699         {\r
700                 return;\r
701         }\r
702 \r
703         Zero(info, sizeof(MEMINFO));\r
704         Zero(&st, sizeof(st));\r
705         st.dwLength = sizeof(st);\r
706 \r
707         GlobalMemoryStatus(&st);\r
708 \r
709         // 論理メモリ量\r
710         info->TotalMemory = (UINT64)st.dwTotalPageFile;\r
711         info->FreeMemory = (UINT64)st.dwAvailPageFile;\r
712         info->UsedMemory = info->TotalMemory - info->FreeMemory;\r
713 \r
714         // 物理メモリ量\r
715         info->TotalPhys = (UINT64)st.dwTotalPhys;\r
716         info->FreePhys = (UINT64)st.dwAvailPhys;\r
717         info->UsedPhys = info->TotalPhys - info->FreePhys;\r
718 }\r
719 \r
720 // シングルインスタンスの作成\r
721 void *Win32NewSingleInstance(char *instance_name)\r
722 {\r
723         WIN32MUTEX *ret;\r
724         char tmp[MAX_SIZE];\r
725         HANDLE hMutex;\r
726         // 引数チェック\r
727         if (instance_name == NULL)\r
728         {\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
733         }\r
734 \r
735         hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, instance_name);\r
736         if (hMutex != NULL)\r
737         {\r
738                 CloseHandle(hMutex);\r
739                 return NULL;\r
740         }\r
741 \r
742         hMutex = CreateMutex(NULL, FALSE, instance_name);\r
743         if (hMutex == NULL)\r
744         {\r
745                 CloseHandle(hMutex);\r
746                 return NULL;\r
747         }\r
748 \r
749         ret = Win32MemoryAlloc(sizeof(WIN32MUTEX));\r
750         ret->hMutex = hMutex;\r
751 \r
752         return (void *)ret;\r
753 }\r
754 \r
755 // シングルインスタンスの解放\r
756 void Win32FreeSingleInstance(void *data)\r
757 {\r
758         WIN32MUTEX *m;\r
759         // 引数チェック\r
760         if (data == NULL)\r
761         {\r
762                 return;\r
763         }\r
764 \r
765         m = (WIN32MUTEX *)data;\r
766         ReleaseMutex(m->hMutex);\r
767         CloseHandle(m->hMutex);\r
768 \r
769         Win32MemoryFree(m);\r
770 }\r
771 \r
772 // 優先順位を高くする\r
773 void Win32SetHighPriority()\r
774 {\r
775         SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);\r
776 }\r
777 \r
778 // 優先順位を戻す\r
779 void Win32RestorePriority()\r
780 {\r
781         SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);\r
782 }\r
783 \r
784 // ノード情報を取得\r
785 char* Win32GetProductId()\r
786 {\r
787         char *product_id;\r
788 \r
789         return CopyStr("--");\r
790 \r
791         // プロダクト ID\r
792         product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");\r
793         if (product_id == NULL)\r
794         {\r
795                 product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");\r
796         }\r
797 \r
798         return product_id;\r
799 }\r
800 \r
801 // 現在サポートされている OS かどうか取得\r
802 bool Win32IsSupportedOs()\r
803 {\r
804         if (Win32GetOsType() == 0)\r
805         {\r
806                 Win32Alert(\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
810                 return false;\r
811         }\r
812 \r
813         return true;\r
814 }\r
815 \r
816 // アラートの表示\r
817 void Win32AlertW(wchar_t *msg, wchar_t *caption)\r
818 {\r
819         char *s;\r
820         // 引数チェック\r
821         if (msg == NULL)\r
822         {\r
823                 msg = L"Alert";\r
824         }\r
825         if (caption == NULL)\r
826         {\r
827                 caption = L"SoftEther UT-VPN Kernel";\r
828         }\r
829 \r
830         s = GetCommandLineStr();\r
831 \r
832         if (SearchStr(s, "win9x_uninstall", 0) == INFINITE && SearchStr(s, "win9x_install", 0) == INFINITE)\r
833         {\r
834                 // Win9x サービスモードのアンインストール時には非表示とする\r
835                 MessageBoxW(NULL, msg, caption, MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);\r
836         }\r
837 \r
838         Free(s);\r
839 }\r
840 void Win32Alert(char *msg, char *caption)\r
841 {\r
842         char *s;\r
843         // 引数チェック\r
844         if (msg == NULL)\r
845         {\r
846                 msg = "Alert";\r
847         }\r
848         if (caption == NULL)\r
849         {\r
850                 caption = "SoftEther UT-VPN Kernel";\r
851         }\r
852 \r
853         s = GetCommandLineStr();\r
854 \r
855         if (SearchStr(s, "win9x_uninstall", 0) == INFINITE && SearchStr(s, "win9x_install", 0) == INFINITE)\r
856         {\r
857                 // Win9x サービスモードのアンインストール時には非表示とする\r
858                 MessageBox(NULL, msg, caption, MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);\r
859         }\r
860 \r
861         Free(s);\r
862 }\r
863 void Win32DebugAlert(char *msg)\r
864 {\r
865         // 引数チェック\r
866         if (msg == NULL)\r
867         {\r
868                 msg = "Alert";\r
869         }\r
870 \r
871         MessageBox(NULL, msg, "Debug", MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);\r
872 }\r
873 \r
874 // OS 情報の取得\r
875 void Win32GetOsInfo(OS_INFO *info)\r
876 {\r
877         UINT type = Win32GetOsType();\r
878         OSVERSIONINFOEX os;\r
879         char tmp[MAX_SIZE];\r
880         // 引数チェック\r
881         if (info == NULL)\r
882         {\r
883                 return;\r
884         }\r
885 \r
886         Zero(&os, sizeof(os));\r
887         os.dwOSVersionInfoSize = sizeof(os);\r
888         GetVersionEx((LPOSVERSIONINFOA)&os);\r
889 \r
890         info->OsType = Win32GetOsType();\r
891         info->OsServicePack = os.wServicePackMajor;\r
892         if (OS_IS_WINDOWS_NT(info->OsType))\r
893         {\r
894                 char *s;\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
899                 {\r
900                         char str[MAX_SIZE];\r
901                         Format(str, sizeof(str), ", %s", s);\r
902                         StrCat(tmp, sizeof(tmp), str);\r
903                         Free(s);\r
904                 }\r
905                 if (os.wServicePackMajor != 0)\r
906                 {\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
910                 }\r
911                 if (s = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "BuildLab"))\r
912                 {\r
913                         char str[MAX_SIZE];\r
914                         Format(str, sizeof(str), " (%s)", s);\r
915                         StrCat(tmp, sizeof(tmp), str);\r
916                         Free(s);\r
917                 }\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
922                 {\r
923                         char str[MAX_SIZE];\r
924                         Format(str, sizeof(str), " %s", s);\r
925                         StrCat(tmp, sizeof(tmp), str);\r
926                         Free(s);\r
927                 }\r
928                 info->KernelVersion = CopyStr(tmp);\r
929         }\r
930         else\r
931         {\r
932                 OSVERSIONINFO os;\r
933                 Zero(&os, sizeof(os));\r
934                 os.dwOSVersionInfoSize = sizeof(os);\r
935                 GetVersionEx(&os);\r
936                 Format(tmp, sizeof(tmp), "Build %u %s", LOWORD(os.dwBuildNumber), os.szCSDVersion);\r
937                 Trim(tmp);\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
942         }\r
943 \r
944         info->OsProductName = CopyStr(OsTypeToStr(info->OsType));\r
945         info->OsVendorName = CopyStr("Microsoft Corporation");\r
946 }\r
947 \r
948 // Windows NT かどうか取得\r
949 bool Win32IsNt()\r
950 {\r
951         OSVERSIONINFO os;\r
952         Zero(&os, sizeof(os));\r
953         os.dwOSVersionInfoSize = sizeof(os);\r
954 \r
955         if (GetVersionEx(&os) == FALSE)\r
956         {\r
957                 // 失敗?\r
958                 return false;\r
959         }\r
960 \r
961         if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)\r
962         {\r
963                 // NT\r
964                 return true;\r
965         }\r
966 \r
967         // 9x\r
968         return false;\r
969 }\r
970 \r
971 // OS 種類の取得\r
972 UINT Win32GetOsType()\r
973 {\r
974         OSVERSIONINFO os;\r
975         Zero(&os, sizeof(os));\r
976         os.dwOSVersionInfoSize = sizeof(os);\r
977 \r
978         if (GetVersionEx(&os) == FALSE)\r
979         {\r
980                 // 失敗?\r
981                 return 0;\r
982         }\r
983 \r
984         if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)\r
985         {\r
986                 // Windows 9x 系\r
987                 if (os.dwMajorVersion == 4)\r
988                 {\r
989                         if (os.dwMinorVersion == 0)\r
990                         {\r
991                                 return OSTYPE_WINDOWS_95;\r
992                         }\r
993                         else if (os.dwMinorVersion == 10)\r
994                         {\r
995                                 return OSTYPE_WINDOWS_98;\r
996                         }\r
997                         else if (os.dwMinorVersion == 90)\r
998                         {\r
999                                 return OSTYPE_WINDOWS_ME;\r
1000                         }\r
1001                         else\r
1002                         {\r
1003                                 return OSTYPE_WINDOWS_UNKNOWN;\r
1004                         }\r
1005                 }\r
1006                 else if (os.dwMajorVersion >= 5)\r
1007                 {\r
1008                         return OSTYPE_WINDOWS_UNKNOWN;\r
1009                 }\r
1010         }\r
1011         else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)\r
1012         {\r
1013                 UINT sp = Win32GetSpVer(os.szCSDVersion);\r
1014                 if (os.dwMajorVersion == 4)\r
1015                 {\r
1016                         if (sp < 6)\r
1017                         {\r
1018                                 // SP6 以前\r
1019                                 return 0;\r
1020                         }\r
1021                 }\r
1022                 if (os.dwMajorVersion < 4)\r
1023                 {\r
1024                         // NT 3.51 以前\r
1025                         return 0;\r
1026                 }\r
1027                 else\r
1028                 {\r
1029                         OSVERSIONINFOEX os;\r
1030                         Zero(&os, sizeof(os));\r
1031                         os.dwOSVersionInfoSize = sizeof(os);\r
1032                         GetVersionEx((LPOSVERSIONINFOA)&os);\r
1033 \r
1034                         if (os.dwMajorVersion == 4)\r
1035                         {\r
1036                                 // Windows NT 4.0\r
1037                                 if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)\r
1038                                 {\r
1039                                         if ((os.wSuiteMask & VER_SUITE_TERMINAL) || (os.wSuiteMask & VER_SUITE_SINGLEUSERTS))\r
1040                                         {\r
1041                                                 return OSTYPE_WINDOWS_NT_4_TERMINAL_SERVER;\r
1042                                         }\r
1043                                         if (os.wSuiteMask & VER_SUITE_ENTERPRISE)\r
1044                                         {\r
1045                                                 return OSTYPE_WINDOWS_NT_4_SERVER_ENTERPRISE;\r
1046                                         }\r
1047                                         if (os.wSuiteMask & VER_SUITE_BACKOFFICE)\r
1048                                         {\r
1049                                                 return OSTYPE_WINDOWS_NT_4_BACKOFFICE;\r
1050                                         }\r
1051                                         if ((os.wSuiteMask & VER_SUITE_SMALLBUSINESS) || (os.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED))\r
1052                                         {\r
1053                                                 return OSTYPE_WINDOWS_NT_4_SMS;\r
1054                                         }\r
1055                                         else\r
1056                                         {\r
1057                                                 return OSTYPE_WINDOWS_NT_4_SERVER;\r
1058                                         }\r
1059                                 }\r
1060                                 else\r
1061                                 {\r
1062                                         return OSTYPE_WINDOWS_NT_4_WORKSTATION;\r
1063                                 }\r
1064                         }\r
1065                         else if (os.dwMajorVersion == 5)\r
1066                         {\r
1067                                 // Windows 2000, XP, Server 2003\r
1068                                 if (os.dwMinorVersion == 0)\r
1069                                 {\r
1070                                         // Windows 2000\r
1071                                         if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)\r
1072                                         {\r
1073                                                 // Server\r
1074                                                 if (os.wSuiteMask & VER_SUITE_DATACENTER)\r
1075                                                 {\r
1076                                                         return OSTYPE_WINDOWS_2000_DATACENTER_SERVER;\r
1077                                                 }\r
1078                                                 else if ((os.wSuiteMask & VER_SUITE_SMALLBUSINESS) || (os.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED))\r
1079                                                 {\r
1080                                                         return OSTYPE_WINDOWS_2000_SBS;\r
1081                                                 }\r
1082                                                 else if (os.wSuiteMask & VER_SUITE_BACKOFFICE)\r
1083                                                 {\r
1084                                                         return OSTYPE_WINDOWS_2000_BACKOFFICE;\r
1085                                                 }\r
1086                                                 else if (os.wSuiteMask & VER_SUITE_ENTERPRISE)\r
1087                                                 {\r
1088                                                         return OSTYPE_WINDOWS_2000_ADVANCED_SERVER;\r
1089                                                 }\r
1090                                                 else\r
1091                                                 {\r
1092                                                         return OSTYPE_WINDOWS_2000_SERVER;\r
1093                                                 }\r
1094                                         }\r
1095                                         else\r
1096                                         {\r
1097                                                 // Client\r
1098                                                 return OSTYPE_WINDOWS_2000_PROFESSIONAL;\r
1099                                         }\r
1100                                 }\r
1101                                 else if (os.dwMinorVersion == 1)\r
1102                                 {\r
1103                                         // Windows XP\r
1104                                         if (os.wSuiteMask & VER_SUITE_PERSONAL)\r
1105                                         {\r
1106                                                 return OSTYPE_WINDOWS_XP_HOME;\r
1107                                         }\r
1108                                         else\r
1109                                         {\r
1110                                                 return OSTYPE_WINDOWS_XP_PROFESSIONAL;\r
1111                                         }\r
1112                                 }\r
1113                                 else if (os.dwMinorVersion == 2)\r
1114                                 {\r
1115                                         // Windows Server 2003\r
1116                                         if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)\r
1117                                         {\r
1118                                                 // Server\r
1119                                                 if (os.wSuiteMask & VER_SUITE_DATACENTER)\r
1120                                                 {\r
1121                                                         return OSTYPE_WINDOWS_2003_DATACENTER;\r
1122                                                 }\r
1123                                                 else if ((os.wSuiteMask & VER_SUITE_SMALLBUSINESS) || (os.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED))\r
1124                                                 {\r
1125                                                         return OSTYPE_WINDOWS_2003_SBS;\r
1126                                                 }\r
1127                                                 else if (os.wSuiteMask & VER_SUITE_BACKOFFICE)\r
1128                                                 {\r
1129                                                         return OSTYPE_WINDOWS_2003_BACKOFFICE;\r
1130                                                 }\r
1131                                                 else if (os.wSuiteMask & VER_SUITE_ENTERPRISE)\r
1132                                                 {\r
1133                                                         return OSTYPE_WINDOWS_2003_ENTERPRISE;\r
1134                                                 }\r
1135                                                 else if (os.wSuiteMask & VER_SUITE_BLADE)\r
1136                                                 {\r
1137                                                         return OSTYPE_WINDOWS_2003_WEB;\r
1138                                                 }\r
1139                                                 else\r
1140                                                 {\r
1141                                                         return OSTYPE_WINDOWS_2003_STANDARD;\r
1142                                                 }\r
1143                                         }\r
1144                                         else\r
1145                                         {\r
1146                                                 // Client (Unknown XP?)\r
1147                                                 return OSTYPE_WINDOWS_XP_PROFESSIONAL;\r
1148                                         }\r
1149                                 }\r
1150                                 else\r
1151                                 {\r
1152                                         // Windows Longhorn\r
1153                                         if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)\r
1154                                         {\r
1155                                                 return OSTYPE_WINDOWS_LONGHORN_SERVER;\r
1156                                         }\r
1157                                         else\r
1158                                         {\r
1159                                                 return OSTYPE_WINDOWS_LONGHORN_PROFESSIONAL;\r
1160                                         }\r
1161                                 }\r
1162                         }\r
1163                         else\r
1164                         {\r
1165                                 if (os.dwMajorVersion == 6 && os.dwMinorVersion == 0)\r
1166                                 {\r
1167                                         // Windows Vista, Server 2008\r
1168                                         if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)\r
1169                                         {\r
1170                                                 return OSTYPE_WINDOWS_LONGHORN_SERVER;\r
1171                                         }\r
1172                                         else\r
1173                                         {\r
1174                                                 return OSTYPE_WINDOWS_LONGHORN_PROFESSIONAL;\r
1175                                         }\r
1176                                 }\r
1177                                 else if (os.dwMajorVersion == 6 && os.dwMinorVersion == 1)\r
1178                                 {\r
1179                                         if (os.wProductType == VER_NT_WORKSTATION)\r
1180                                         {\r
1181                                                 // Windows 7\r
1182                                                 return OSTYPE_WINDOWS_7;\r
1183                                         }\r
1184                                         else\r
1185                                         {\r
1186                                                 // Windows Server 2008 R2\r
1187                                                 return OSTYPE_WINDOWS_SERVER_2008_R2;\r
1188                                         }\r
1189                                 }\r
1190                                 else\r
1191                                 {\r
1192                                         if (os.wProductType == VER_NT_WORKSTATION)\r
1193                                         {\r
1194                                                 // Windows 8\r
1195                                                 return OSTYPE_WINDOWS_8;\r
1196                                         }\r
1197                                         else\r
1198                                         {\r
1199                                                 // Windows Server 8\r
1200                                                 return OSTYPE_WINDOWS_SERVER_2008_R2;\r
1201                                         }\r
1202                                 }\r
1203                         }\r
1204                 }\r
1205         }\r
1206 \r
1207         // 判別できない\r
1208         return 0;\r
1209 }\r
1210 \r
1211 // 文字列から SP のバージョンを取得する\r
1212 UINT Win32GetSpVer(char *str)\r
1213 {\r
1214         UINT ret, i;\r
1215         TOKEN_LIST *t;\r
1216         // 引数チェック\r
1217         if (str == NULL)\r
1218         {\r
1219                 return 0;\r
1220         }\r
1221 \r
1222         t = ParseToken(str, NULL);\r
1223         if (t == NULL)\r
1224         {\r
1225                 return 0;\r
1226         }\r
1227 \r
1228         ret = 0;\r
1229         for (i = 0;i < t->NumTokens;i++)\r
1230         {\r
1231                 ret = ToInt(t->Token[i]);\r
1232                 if (ret != 0)\r
1233                 {\r
1234                         break;\r
1235                 }\r
1236         }\r
1237 \r
1238         FreeToken(t);\r
1239 \r
1240         return ret;\r
1241 }\r
1242 \r
1243 // プロセスの強制終了\r
1244 bool Win32TerminateProcess(void *handle)\r
1245 {\r
1246         HANDLE h;\r
1247         // 引数チェック\r
1248         if (handle == NULL)\r
1249         {\r
1250                 return false;\r
1251         }\r
1252 \r
1253         h = (HANDLE)handle;\r
1254 \r
1255         TerminateProcess(h, 0);\r
1256 \r
1257         return true;\r
1258 }\r
1259 \r
1260 // プロセスを閉じる\r
1261 void Win32CloseProcess(void *handle)\r
1262 {\r
1263         // 引数チェック\r
1264         if (handle == NULL)\r
1265         {\r
1266                 return;\r
1267         }\r
1268 \r
1269         CloseHandle((HANDLE)handle);\r
1270 }\r
1271 \r
1272 // 指定されたプロセスが生きているかどうかチェック\r
1273 bool Win32IsProcessAlive(void *handle)\r
1274 {\r
1275         HANDLE h;\r
1276         // 引数チェック\r
1277         if (handle == NULL)\r
1278         {\r
1279                 return false;\r
1280         }\r
1281 \r
1282         h = (HANDLE)handle;\r
1283 \r
1284         if (WaitForSingleObject(h, 0) == WAIT_OBJECT_0)\r
1285         {\r
1286                 return false;\r
1287         }\r
1288 \r
1289         return true;\r
1290 }\r
1291 \r
1292 // プロセスの終了を待機する\r
1293 bool Win32WaitProcess(void *h, UINT timeout)\r
1294 {\r
1295         // 引数チェック\r
1296         if (h == NULL)\r
1297         {\r
1298                 return false;\r
1299         }\r
1300         if (timeout == 0)\r
1301         {\r
1302                 timeout = INFINITE;\r
1303         }\r
1304 \r
1305         if (WaitForSingleObject((HANDLE)h, timeout) == WAIT_TIMEOUT)\r
1306         {\r
1307                 return false;\r
1308         }\r
1309 \r
1310         return true;\r
1311 }\r
1312 \r
1313 // プロセスの起動 (ハンドルを返す)\r
1314 void *Win32RunExW(wchar_t *filename, wchar_t *arg, bool hide)\r
1315 {\r
1316         return Win32RunEx2W(filename, arg, hide, NULL);\r
1317 }\r
1318 void *Win32RunEx2W(wchar_t *filename, wchar_t *arg, bool hide, UINT *process_id)\r
1319 {\r
1320         return Win32RunEx3W(filename, arg, hide, process_id, false);\r
1321 }\r
1322 void *Win32RunEx3W(wchar_t *filename, wchar_t *arg, bool hide, UINT *process_id, bool disableWow)\r
1323 {\r
1324         STARTUPINFOW info;\r
1325         PROCESS_INFORMATION ret;\r
1326         wchar_t cmdline[MAX_SIZE];\r
1327         wchar_t name[MAX_PATH];\r
1328         void *p;\r
1329         // 引数チェック\r
1330         if (filename == NULL)\r
1331         {\r
1332                 return NULL;\r
1333         }\r
1334 \r
1335         if (IsNt() == false)\r
1336         {\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
1340 \r
1341                 Free(filename_a);\r
1342                 Free(arg_a);\r
1343 \r
1344                 return ret;\r
1345         }\r
1346 \r
1347         UniStrCpy(name, sizeof(name), filename);\r
1348         UniTrim(name);\r
1349 \r
1350         if (UniSearchStr(name, L"\"", 0) == INFINITE)\r
1351         {\r
1352                 if (arg == NULL)\r
1353                 {\r
1354                         UniFormat(cmdline, sizeof(cmdline), L"%s", name);\r
1355                 }\r
1356                 else\r
1357                 {\r
1358                         UniFormat(cmdline, sizeof(cmdline), L"%s %s", name, arg);\r
1359                 }\r
1360         }\r
1361         else\r
1362         {\r
1363                 if (arg == NULL)\r
1364                 {\r
1365                         UniFormat(cmdline, sizeof(cmdline), L"\"%s\"", name);\r
1366                 }\r
1367                 else\r
1368                 {\r
1369                         UniFormat(cmdline, sizeof(cmdline), L"\"%s\" %s", name, arg);\r
1370                 }\r
1371         }\r
1372 \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
1378 \r
1379         UniTrim(cmdline);\r
1380 \r
1381         if (disableWow)\r
1382         {\r
1383                 p = MsDisableWow64FileSystemRedirection();\r
1384         }\r
1385 \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
1389         {\r
1390                 if (disableWow)\r
1391                 {\r
1392                         MsRestoreWow64FileSystemRedirection(p);\r
1393                 }\r
1394                 return NULL;\r
1395         }\r
1396 \r
1397         if (disableWow)\r
1398         {\r
1399                 MsRestoreWow64FileSystemRedirection(p);\r
1400         }\r
1401 \r
1402         if (process_id != NULL)\r
1403         {\r
1404                 *process_id = ret.dwProcessId;\r
1405         }\r
1406 \r
1407         CloseHandle(ret.hThread);\r
1408         return ret.hProcess;\r
1409 }\r
1410 void *Win32RunEx(char *filename, char *arg, bool hide)\r
1411 {\r
1412         return Win32RunEx2(filename, arg, hide, NULL);\r
1413 }\r
1414 void *Win32RunEx2(char *filename, char *arg, bool hide, UINT *process_id)\r
1415 {\r
1416         return Win32RunEx3(filename, arg, hide, process_id, false);\r
1417 }\r
1418 void *Win32RunEx3(char *filename, char *arg, bool hide, UINT *process_id, bool disableWow)\r
1419 {\r
1420         STARTUPINFO info;\r
1421         PROCESS_INFORMATION ret;\r
1422         char cmdline[MAX_SIZE];\r
1423         char name[MAX_PATH];\r
1424         void *p = NULL;\r
1425         // 引数チェック\r
1426         if (filename == NULL)\r
1427         {\r
1428                 return NULL;\r
1429         }\r
1430 \r
1431         StrCpy(name, sizeof(name), filename);\r
1432         Trim(name);\r
1433 \r
1434         if (SearchStr(name, "\"", 0) == INFINITE)\r
1435         {\r
1436                 if (arg == NULL)\r
1437                 {\r
1438                         Format(cmdline, sizeof(cmdline), "%s", name);\r
1439                 }\r
1440                 else\r
1441                 {\r
1442                         Format(cmdline, sizeof(cmdline), "%s %s", name, arg);\r
1443                 }\r
1444         }\r
1445         else\r
1446         {\r
1447                 if (arg == NULL)\r
1448                 {\r
1449                         Format(cmdline, sizeof(cmdline), "\"%s\"", name);\r
1450                 }\r
1451                 else\r
1452                 {\r
1453                         Format(cmdline, sizeof(cmdline), "\"%s\" %s", name, arg);\r
1454                 }\r
1455         }\r
1456 \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
1462 \r
1463         Trim(cmdline);\r
1464 \r
1465         if (disableWow)\r
1466         {\r
1467                 p = MsDisableWow64FileSystemRedirection();\r
1468         }\r
1469 \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
1473         {\r
1474                 if (disableWow)\r
1475                 {\r
1476                         MsRestoreWow64FileSystemRedirection(p);\r
1477                 }\r
1478                 return NULL;\r
1479         }\r
1480         if (disableWow)\r
1481         {\r
1482                 MsRestoreWow64FileSystemRedirection(p);\r
1483         }\r
1484 \r
1485         if (process_id != NULL)\r
1486         {\r
1487                 *process_id = ret.dwProcessId;\r
1488         }\r
1489 \r
1490         CloseHandle(ret.hThread);\r
1491         return ret.hProcess;\r
1492 }\r
1493 \r
1494 // プロセスの起動\r
1495 bool Win32RunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait)\r
1496 {\r
1497         STARTUPINFOW info;\r
1498         PROCESS_INFORMATION ret;\r
1499         wchar_t cmdline[MAX_SIZE];\r
1500         wchar_t name[MAX_PATH];\r
1501         // 引数チェック\r
1502         if (filename == NULL)\r
1503         {\r
1504                 return false;\r
1505         }\r
1506 \r
1507         if (IsNt() == false)\r
1508         {\r
1509                 char *filename_a = CopyUniToStr(filename);\r
1510                 char *arg_a = CopyUniToStr(arg);\r
1511                 bool ret;\r
1512 \r
1513                 ret = Win32Run(filename_a, arg_a, hide, wait);\r
1514 \r
1515                 Free(filename_a);\r
1516                 Free(arg_a);\r
1517 \r
1518                 return ret;\r
1519         }\r
1520 \r
1521         UniStrCpy(name, sizeof(name), filename);\r
1522         UniTrim(name);\r
1523 \r
1524         if (UniSearchStr(name, L"\"", 0) == INFINITE)\r
1525         {\r
1526                 if (arg == NULL)\r
1527                 {\r
1528                         UniFormat(cmdline, sizeof(cmdline), L"%s", name);\r
1529                 }\r
1530                 else\r
1531                 {\r
1532                         UniFormat(cmdline, sizeof(cmdline), L"%s %s", name, arg);\r
1533                 }\r
1534         }\r
1535         else\r
1536         {\r
1537                 if (arg == NULL)\r
1538                 {\r
1539                         UniFormat(cmdline, sizeof(cmdline), L"\"%s\"", name);\r
1540                 }\r
1541                 else\r
1542                 {\r
1543                         UniFormat(cmdline, sizeof(cmdline), L"\"%s\" %s", name, arg);\r
1544                 }\r
1545         }\r
1546 \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
1552 \r
1553         UniTrim(cmdline);\r
1554 \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
1558         {\r
1559                 return false;\r
1560         }\r
1561 \r
1562         if (wait)\r
1563         {\r
1564                 WaitForSingleObject(ret.hProcess, INFINITE);\r
1565         }\r
1566 \r
1567         CloseHandle(ret.hThread);\r
1568         CloseHandle(ret.hProcess);\r
1569 \r
1570         return true;\r
1571 }\r
1572 bool Win32Run(char *filename, char *arg, bool hide, bool wait)\r
1573 {\r
1574         STARTUPINFO info;\r
1575         PROCESS_INFORMATION ret;\r
1576         char cmdline[MAX_SIZE];\r
1577         char name[MAX_PATH];\r
1578         // 引数チェック\r
1579         if (filename == NULL)\r
1580         {\r
1581                 return false;\r
1582         }\r
1583 \r
1584         StrCpy(name, sizeof(name), filename);\r
1585         Trim(name);\r
1586 \r
1587         if (SearchStr(name, "\"", 0) == INFINITE)\r
1588         {\r
1589                 if (arg == NULL)\r
1590                 {\r
1591                         Format(cmdline, sizeof(cmdline), "%s", name);\r
1592                 }\r
1593                 else\r
1594                 {\r
1595                         Format(cmdline, sizeof(cmdline), "%s %s", name, arg);\r
1596                 }\r
1597         }\r
1598         else\r
1599         {\r
1600                 if (arg == NULL)\r
1601                 {\r
1602                         Format(cmdline, sizeof(cmdline), "\"%s\"", name);\r
1603                 }\r
1604                 else\r
1605                 {\r
1606                         Format(cmdline, sizeof(cmdline), "\"%s\" %s", name, arg);\r
1607                 }\r
1608         }\r
1609 \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
1615 \r
1616         Trim(cmdline);\r
1617 \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
1621         {\r
1622                 return false;\r
1623         }\r
1624 \r
1625         if (wait)\r
1626         {\r
1627                 WaitForSingleObject(ret.hProcess, INFINITE);\r
1628         }\r
1629 \r
1630         CloseHandle(ret.hThread);\r
1631         CloseHandle(ret.hProcess);\r
1632 \r
1633         return true;\r
1634 }\r
1635 \r
1636 // スレッド ID の取得\r
1637 UINT Win32ThreadId()\r
1638 {\r
1639         return GetCurrentThreadId();\r
1640 }\r
1641 \r
1642 // ファイル名の変更\r
1643 bool Win32FileRenameW(wchar_t *old_name, wchar_t *new_name)\r
1644 {\r
1645         // 引数チェック\r
1646         if (old_name == NULL || new_name == NULL)\r
1647         {\r
1648                 return false;\r
1649         }\r
1650 \r
1651         if (IsNt() == false)\r
1652         {\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
1656 \r
1657                 Free(old_name_a);\r
1658                 Free(new_name_a);\r
1659 \r
1660                 return ret;\r
1661         }\r
1662 \r
1663         // リネーム\r
1664         if (MoveFileW(old_name, new_name) == FALSE)\r
1665         {\r
1666                 return false;\r
1667         }\r
1668 \r
1669         return true;\r
1670 }\r
1671 bool Win32FileRename(char *old_name, char *new_name)\r
1672 {\r
1673         // 引数チェック\r
1674         if (old_name == NULL || new_name == NULL)\r
1675         {\r
1676                 return false;\r
1677         }\r
1678 \r
1679         // リネーム\r
1680         if (MoveFile(old_name, new_name) == FALSE)\r
1681         {\r
1682                 return false;\r
1683         }\r
1684 \r
1685         return true;\r
1686 }\r
1687 \r
1688 // EXE ファイルが存在しているディレクトリ名を取得する\r
1689 void Win32GetExeDirW(wchar_t *name, UINT size)\r
1690 {\r
1691         wchar_t exe_path[MAX_SIZE];\r
1692         wchar_t exe_dir[MAX_SIZE];\r
1693         // 引数チェック\r
1694         if (name == NULL)\r
1695         {\r
1696                 return;\r
1697         }\r
1698 \r
1699         if (IsNt() == false)\r
1700         {\r
1701                 char name_a[MAX_PATH];\r
1702 \r
1703                 Win32GetExeDir(name_a, sizeof(name_a));\r
1704 \r
1705                 StrToUni(name, size, name_a);\r
1706 \r
1707                 return;\r
1708         }\r
1709 \r
1710         // EXE ファイル名を取得\r
1711         GetModuleFileNameW(NULL, exe_path, sizeof(exe_path));\r
1712 \r
1713         // ディレクトリ名を取得\r
1714         Win32GetDirFromPathW(exe_dir, sizeof(exe_dir), exe_path);\r
1715 \r
1716         UniStrCpy(name, size, exe_dir);\r
1717 }\r
1718 void Win32GetExeDir(char *name, UINT size)\r
1719 {\r
1720         char exe_path[MAX_SIZE];\r
1721         char exe_dir[MAX_SIZE];\r
1722         // 引数チェック\r
1723         if (name == NULL)\r
1724         {\r
1725                 return;\r
1726         }\r
1727 \r
1728         // EXE ファイル名を取得\r
1729         GetModuleFileName(NULL, exe_path, sizeof(exe_path));\r
1730 \r
1731         // ディレクトリ名を取得\r
1732         Win32GetDirFromPath(exe_dir, sizeof(exe_dir), exe_path);\r
1733 \r
1734         StrCpy(name, size, exe_dir);\r
1735 }\r
1736 \r
1737 // 終端の \ を抜く\r
1738 void Win32NukuEnW(wchar_t *dst, UINT size, wchar_t *src)\r
1739 {\r
1740         wchar_t str[MAX_SIZE];\r
1741         int i;\r
1742         if (src)\r
1743         {\r
1744                 UniStrCpy(str, sizeof(str), src);\r
1745         }\r
1746         else\r
1747         {\r
1748                 UniStrCpy(str, sizeof(str), dst);\r
1749         }\r
1750         i = UniStrLen(str);\r
1751         if (str[i - 1] == L'\\')\r
1752         {\r
1753                 str[i - 1] = 0;\r
1754         }\r
1755         UniStrCpy(dst, size, str);\r
1756 }\r
1757 void Win32NukuEn(char *dst, UINT size, char *src)\r
1758 {\r
1759         char str[MAX_SIZE];\r
1760         int i;\r
1761         if (src)\r
1762         {\r
1763                 StrCpy(str, sizeof(str), src);\r
1764         }\r
1765         else\r
1766         {\r
1767                 StrCpy(str, sizeof(str), dst);\r
1768         }\r
1769         i = StrLen(str);\r
1770         if (str[i - 1] == '\\')\r
1771         {\r
1772                 str[i - 1] = 0;\r
1773         }\r
1774         StrCpy(dst, size, str);\r
1775 }\r
1776 \r
1777 // ディレクトリ名をパスから取得\r
1778 void Win32GetDirFromPathW(wchar_t *dst, UINT size, wchar_t *src)\r
1779 {\r
1780         wchar_t str[MAX_SIZE];\r
1781         int i,len;\r
1782         wchar_t c;\r
1783         wchar_t tmp[MAX_SIZE];\r
1784         int wp;\r
1785         if (src)\r
1786         {\r
1787                 UniStrCpy(str, sizeof(str), src);\r
1788         }\r
1789         else\r
1790         {\r
1791                 UniStrCpy(str, sizeof(str), dst);\r
1792         }\r
1793         Win32NukuEnW(str, sizeof(str), NULL);\r
1794         wp = 0;\r
1795         len = UniStrLen(str);\r
1796         dst[0] = 0;\r
1797         for (i = 0;i < len;i++)\r
1798         {\r
1799                 c = str[i];\r
1800                 switch (c)\r
1801                 {\r
1802                 case L'\\':\r
1803                         tmp[wp] = 0;\r
1804                         wp = 0;\r
1805                         UniStrCat(dst, size, tmp);\r
1806                         UniStrCat(dst, size, L"\\");\r
1807                         break;\r
1808                 default:\r
1809                         tmp[wp] = c;\r
1810                         wp++;\r
1811                         break;\r
1812                 }\r
1813         }\r
1814         Win32NukuEnW(dst, size, NULL);\r
1815 }\r
1816 void Win32GetDirFromPath(char *dst, UINT size, char *src)\r
1817 {\r
1818         char str[MAX_SIZE];\r
1819         int i,len;\r
1820         char c;\r
1821         char tmp[MAX_SIZE];\r
1822         int wp;\r
1823         if (src)\r
1824         {\r
1825                 StrCpy(str, sizeof(str), src);\r
1826         }\r
1827         else\r
1828         {\r
1829                 StrCpy(str, sizeof(str), dst);\r
1830         }\r
1831         Win32NukuEn(str, sizeof(str), NULL);\r
1832         wp = 0;\r
1833         len = StrLen(str);\r
1834         dst[0] = 0;\r
1835         for (i = 0;i < len;i++)\r
1836         {\r
1837                 c = str[i];\r
1838                 switch (c)\r
1839                 {\r
1840                 case '\\':\r
1841                         tmp[wp] = 0;\r
1842                         wp = 0;\r
1843                         StrCat(dst, size, tmp);\r
1844                         StrCat(dst, size, "\\");\r
1845                         break;\r
1846                 default:\r
1847                         tmp[wp] = c;\r
1848                         wp++;\r
1849                         break;\r
1850                 }\r
1851         }\r
1852         Win32NukuEn(dst, size, NULL);\r
1853 }\r
1854 \r
1855 // ディレクトリの削除\r
1856 bool Win32DeleteDirW(wchar_t *name)\r
1857 {\r
1858         // 引数チェック\r
1859         if (name == NULL)\r
1860         {\r
1861                 return false;\r
1862         }\r
1863 \r
1864         if (IsNt() == false)\r
1865         {\r
1866                 char *name_a = CopyUniToStr(name);\r
1867                 bool ret = Win32DeleteDir(name_a);\r
1868 \r
1869                 Free(name_a);\r
1870 \r
1871                 return ret;\r
1872         }\r
1873 \r
1874         if (RemoveDirectoryW(name) == FALSE)\r
1875         {\r
1876                 return false;\r
1877         }\r
1878         return true;\r
1879 }\r
1880 bool Win32DeleteDir(char *name)\r
1881 {\r
1882         // 引数チェック\r
1883         if (name == NULL)\r
1884         {\r
1885                 return false;\r
1886         }\r
1887 \r
1888         if (RemoveDirectory(name) == FALSE)\r
1889         {\r
1890                 return false;\r
1891         }\r
1892         return true;\r
1893 }\r
1894 \r
1895 // ディレクトリの作成\r
1896 bool Win32MakeDirW(wchar_t *name)\r
1897 {\r
1898         // 引数チェック\r
1899         if (name == NULL)\r
1900         {\r
1901                 return false;\r
1902         }\r
1903 \r
1904         if (IsNt() == false)\r
1905         {\r
1906                 char *name_a = CopyUniToStr(name);\r
1907                 bool ret = Win32MakeDir(name_a);\r
1908 \r
1909                 Free(name_a);\r
1910 \r
1911                 return ret;\r
1912         }\r
1913 \r
1914         if (CreateDirectoryW(name, NULL) == FALSE)\r
1915         {\r
1916                 return false;\r
1917         }\r
1918 \r
1919         return true;\r
1920 }\r
1921 bool Win32MakeDir(char *name)\r
1922 {\r
1923         // 引数チェック\r
1924         if (name == NULL)\r
1925         {\r
1926                 return false;\r
1927         }\r
1928 \r
1929         if (CreateDirectory(name, NULL) == FALSE)\r
1930         {\r
1931                 return false;\r
1932         }\r
1933 \r
1934         return true;\r
1935 }\r
1936 \r
1937 // ファイルの削除\r
1938 bool Win32FileDeleteW(wchar_t *name)\r
1939 {\r
1940         // 引数チェック\r
1941         if (name == NULL)\r
1942         {\r
1943                 return false;\r
1944         }\r
1945 \r
1946         if (IsNt() == false)\r
1947         {\r
1948                 bool ret;\r
1949                 char *name_a = CopyUniToStr(name);\r
1950 \r
1951                 ret = Win32FileDelete(name_a);\r
1952 \r
1953                 Free(name_a);\r
1954 \r
1955                 return ret;\r
1956         }\r
1957 \r
1958         if (DeleteFileW(name) == FALSE)\r
1959         {\r
1960                 return false;\r
1961         }\r
1962         return true;\r
1963 }\r
1964 bool Win32FileDelete(char *name)\r
1965 {\r
1966         // 引数チェック\r
1967         if (name == NULL)\r
1968         {\r
1969                 return false;\r
1970         }\r
1971 \r
1972         if (DeleteFile(name) == FALSE)\r
1973         {\r
1974                 return false;\r
1975         }\r
1976         return true;\r
1977 }\r
1978 \r
1979 // ファイルのシーク\r
1980 bool Win32FileSeek(void *pData, UINT mode, int offset)\r
1981 {\r
1982         WIN32IO *p;\r
1983         DWORD ret;\r
1984         // 引数チェック\r
1985         if (pData == NULL)\r
1986         {\r
1987                 return false;\r
1988         }\r
1989         if (mode != FILE_BEGIN && mode != FILE_END && mode != FILE_CURRENT)\r
1990         {\r
1991                 return false;\r
1992         }\r
1993 \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
1997         {\r
1998                 return false;\r
1999         }\r
2000         return true;\r
2001 }\r
2002 \r
2003 // ファイルサイズの取得\r
2004 UINT64 Win32FileSize(void *pData)\r
2005 {\r
2006         WIN32IO *p;\r
2007         UINT64 ret;\r
2008         DWORD tmp;\r
2009         // 引数チェック\r
2010         if (pData == NULL)\r
2011         {\r
2012                 return 0;\r
2013         }\r
2014 \r
2015         p = (WIN32IO *)pData;\r
2016         tmp = 0;\r
2017         ret = GetFileSize(p->hFile, &tmp);\r
2018         if (ret == (DWORD)-1)\r
2019         {\r
2020                 return 0;\r
2021         }\r
2022 \r
2023         if (tmp != 0)\r
2024         {\r
2025                 ret += (UINT64)tmp * 4294967296ULL;\r
2026         }\r
2027 \r
2028         return ret;\r
2029 }\r
2030 \r
2031 // ファイルに書き込む\r
2032 bool Win32FileWrite(void *pData, void *buf, UINT size)\r
2033 {\r
2034         WIN32IO *p;\r
2035         DWORD write_size;\r
2036         // 引数チェック\r
2037         if (pData == NULL || buf == NULL || size == 0)\r
2038         {\r
2039                 return false;\r
2040         }\r
2041 \r
2042         p = (WIN32IO *)pData;\r
2043         if (WriteFile(p->hFile, buf, size, &write_size, NULL) == FALSE)\r
2044         {\r
2045                 return false;\r
2046         }\r
2047 \r
2048         if (write_size != size)\r
2049         {\r
2050                 return false;\r
2051         }\r
2052 \r
2053         return true;\r
2054 }\r
2055 \r
2056 // ファイルから読み込む\r
2057 bool Win32FileRead(void *pData, void *buf, UINT size)\r
2058 {\r
2059         WIN32IO *p;\r
2060         DWORD read_size;\r
2061         // 引数チェック\r
2062         if (pData == NULL || buf == NULL || size == 0)\r
2063         {\r
2064                 return false;\r
2065         }\r
2066 \r
2067         p = (WIN32IO *)pData;\r
2068         if (ReadFile(p->hFile, buf, size, &read_size, NULL) == FALSE)\r
2069         {\r
2070                 return false;\r
2071         }\r
2072 \r
2073         if (read_size != size)\r
2074         {\r
2075                 return false;\r
2076         }\r
2077         \r
2078         return true;;\r
2079 }\r
2080 \r
2081 // ファイルを閉じる\r
2082 void Win32FileClose(void *pData, bool no_flush)\r
2083 {\r
2084         WIN32IO *p;\r
2085         // 引数チェック\r
2086         if (pData == NULL)\r
2087         {\r
2088                 return;\r
2089         }\r
2090 \r
2091         p = (WIN32IO *)pData;\r
2092         if (p->WriteMode && no_flush == false)\r
2093         {\r
2094                 FlushFileBuffers(p->hFile);\r
2095         }\r
2096         CloseHandle(p->hFile);\r
2097         p->hFile = NULL;\r
2098 \r
2099         // メモリ解放\r
2100         Win32MemoryFree(p);\r
2101 }\r
2102 \r
2103 // ファイルをフラッシュする\r
2104 void Win32FileFlush(void *pData)\r
2105 {\r
2106         WIN32IO *p;\r
2107         // 引数チェック\r
2108         if (pData == NULL)\r
2109         {\r
2110                 return;\r
2111         }\r
2112 \r
2113         p = (WIN32IO *)pData;\r
2114         if (p->WriteMode)\r
2115         {\r
2116                 FlushFileBuffers(p->hFile);\r
2117         }\r
2118 }\r
2119 \r
2120 // ファイルを開く\r
2121 void *Win32FileOpenW(wchar_t *name, bool write_mode, bool read_lock)\r
2122 {\r
2123         WIN32IO *p;\r
2124         HANDLE h;\r
2125         DWORD lock_mode;\r
2126         // 引数チェック\r
2127         if (name == NULL)\r
2128         {\r
2129                 return NULL;\r
2130         }\r
2131 \r
2132         if (IsNt() == false)\r
2133         {\r
2134                 void *ret;\r
2135                 char *name_a = CopyUniToStr(name);\r
2136 \r
2137                 ret = Win32FileOpen(name_a, write_mode, read_lock);\r
2138 \r
2139                 Free(name_a);\r
2140 \r
2141                 return ret;\r
2142         }\r
2143 \r
2144         if (write_mode)\r
2145         {\r
2146                 lock_mode = FILE_SHARE_READ;\r
2147         }\r
2148         else\r
2149         {\r
2150                 if (read_lock == false)\r
2151                 {\r
2152                         lock_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;\r
2153                 }\r
2154                 else\r
2155                 {\r
2156                         lock_mode = FILE_SHARE_READ;\r
2157                 }\r
2158         }\r
2159 \r
2160         // ファイルを開く\r
2161         h = CreateFileW(name,\r
2162                 (write_mode ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ),\r
2163                 lock_mode,\r
2164                 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\r
2165         if (h == INVALID_HANDLE_VALUE)\r
2166         {\r
2167                 UINT ret = GetLastError();\r
2168                 // 失敗\r
2169                 return NULL;\r
2170         }\r
2171 \r
2172         // メモリ確保\r
2173         p = Win32MemoryAlloc(sizeof(WIN32IO));\r
2174         // ハンドル格納\r
2175         p->hFile = h;\r
2176 \r
2177         p->WriteMode = write_mode;\r
2178 \r
2179         return (void *)p;\r
2180 }\r
2181 void *Win32FileOpen(char *name, bool write_mode, bool read_lock)\r
2182 {\r
2183         WIN32IO *p;\r
2184         HANDLE h;\r
2185         DWORD lock_mode;\r
2186         // 引数チェック\r
2187         if (name == NULL)\r
2188         {\r
2189                 return NULL;\r
2190         }\r
2191 \r
2192         if (write_mode)\r
2193         {\r
2194                 lock_mode = FILE_SHARE_READ;\r
2195         }\r
2196         else\r
2197         {\r
2198                 if (read_lock == false)\r
2199                 {\r
2200                         lock_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;\r
2201                 }\r
2202                 else\r
2203                 {\r
2204                         lock_mode = FILE_SHARE_READ;\r
2205                 }\r
2206         }\r
2207 \r
2208         // ファイルを開く\r
2209         h = CreateFile(name,\r
2210                 (write_mode ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ),\r
2211                 lock_mode,\r
2212                 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\r
2213         if (h == INVALID_HANDLE_VALUE)\r
2214         {\r
2215                 UINT ret = GetLastError();\r
2216                 // 失敗\r
2217                 return NULL;\r
2218         }\r
2219 \r
2220         // メモリ確保\r
2221         p = Win32MemoryAlloc(sizeof(WIN32IO));\r
2222         // ハンドル格納\r
2223         p->hFile = h;\r
2224 \r
2225         p->WriteMode = write_mode;\r
2226 \r
2227         return (void *)p;\r
2228 }\r
2229 \r
2230 // ファイルを作成する\r
2231 void *Win32FileCreateW(wchar_t *name)\r
2232 {\r
2233         WIN32IO *p;\r
2234         HANDLE h;\r
2235         // 引数チェック\r
2236         if (name == NULL)\r
2237         {\r
2238                 return NULL;\r
2239         }\r
2240 \r
2241         if (IsNt() == false)\r
2242         {\r
2243                 void *ret;\r
2244                 char *name_a = CopyUniToStr(name);\r
2245 \r
2246                 ret = Win32FileCreate(name_a);\r
2247 \r
2248                 Free(name_a);\r
2249 \r
2250                 return ret;\r
2251         }\r
2252 \r
2253         // ファイルを作成する\r
2254         h = CreateFileW(name, GENERIC_READ | GENERIC_WRITE,\r
2255                 FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,\r
2256                 NULL);\r
2257         if (h == INVALID_HANDLE_VALUE)\r
2258         {\r
2259                 h = CreateFileW(name, GENERIC_READ | GENERIC_WRITE,\r
2260                         FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN,\r
2261                         NULL);\r
2262                 if (h == INVALID_HANDLE_VALUE)\r
2263                 {\r
2264                         return NULL;\r
2265                 }\r
2266         }\r
2267 \r
2268         // メモリ確保\r
2269         p = Win32MemoryAlloc(sizeof(WIN32IO));\r
2270         // ハンドル格納\r
2271         p->hFile = h;\r
2272 \r
2273         p->WriteMode = true;\r
2274 \r
2275         return (void *)p;\r
2276 }\r
2277 void *Win32FileCreate(char *name)\r
2278 {\r
2279         WIN32IO *p;\r
2280         HANDLE h;\r
2281         // 引数チェック\r
2282         if (name == NULL)\r
2283         {\r
2284                 return NULL;\r
2285         }\r
2286 \r
2287         // ファイルを作成する\r
2288         h = CreateFile(name, GENERIC_READ | GENERIC_WRITE,\r
2289                 FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,\r
2290                 NULL);\r
2291         if (h == INVALID_HANDLE_VALUE)\r
2292         {\r
2293                 h = CreateFile(name, GENERIC_READ | GENERIC_WRITE,\r
2294                         FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN,\r
2295                         NULL);\r
2296                 if (h == INVALID_HANDLE_VALUE)\r
2297                 {\r
2298                         return NULL;\r
2299                 }\r
2300         }\r
2301 \r
2302         // メモリ確保\r
2303         p = Win32MemoryAlloc(sizeof(WIN32IO));\r
2304         // ハンドル格納\r
2305         p->hFile = h;\r
2306 \r
2307         p->WriteMode = true;\r
2308 \r
2309         return (void *)p;\r
2310 }\r
2311 \r
2312 #define SIZE_OF_CALLSTACK_SYM   10000\r
2313 #define CALLSTACK_DEPTH                 12\r
2314 \r
2315 // コールスタックの取得\r
2316 CALLSTACK_DATA *Win32GetCallStack()\r
2317 {\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
2321         STACKFRAME64 sf;\r
2322         CALLSTACK_DATA *cs = NULL, *s;\r
2323 \r
2324 #ifdef  CPU_64\r
2325         CONTEXT context;\r
2326 #endif  // CPU_64\r
2327 \r
2328         bool ret;\r
2329         UINT depth = 0;\r
2330 \r
2331 #ifndef CPU_64\r
2332         // レジスタ取得 (32 bit)\r
2333         __asm\r
2334         {\r
2335                 mov current_esp32, esp\r
2336                 mov current_ebp32, ebp\r
2337         };\r
2338 \r
2339         current_eip32 = (DWORD)Win32GetCallStack;\r
2340 \r
2341         current_eip = (UINT64)current_eip32;\r
2342         current_esp = (UINT64)current_esp32;\r
2343         current_ebp = (UINT64)current_ebp32;\r
2344 #else   // CPU_64\r
2345         // レジスタ取得 (64 bit)\r
2346         Zero(&context, sizeof(context));\r
2347         context.ContextFlags = CONTEXT_FULL;\r
2348         RtlCaptureContext(&context);\r
2349 #endif  // CPU_64\r
2350 \r
2351         Zero(&sf, sizeof(sf));\r
2352 \r
2353 #ifndef CPU_64\r
2354         sf.AddrPC.Offset = current_eip;\r
2355         sf.AddrStack.Offset = current_esp;\r
2356         sf.AddrFrame.Offset = current_ebp;\r
2357 #else   // CPU_64\r
2358         sf.AddrPC.Offset = context.Rip;\r
2359         sf.AddrStack.Offset = context.Rsp;\r
2360         sf.AddrFrame.Offset = context.Rsp;\r
2361 #endif  // CPU_64\r
2362 \r
2363         sf.AddrPC.Mode = AddrModeFlat;\r
2364         sf.AddrStack.Mode = AddrModeFlat;\r
2365         sf.AddrFrame.Mode = AddrModeFlat;\r
2366 \r
2367         while (true)\r
2368         {\r
2369                 DWORD type = IMAGE_FILE_MACHINE_I386;\r
2370 \r
2371 #ifdef  CPU_64\r
2372                 type = IMAGE_FILE_MACHINE_AMD64;\r
2373 #endif  // CPU_64\r
2374 \r
2375                 if ((depth++) >= CALLSTACK_DEPTH)\r
2376                 {\r
2377                         break;\r
2378                 }\r
2379 \r
2380 #ifndef CPU_64\r
2381                 ret = StackWalk64(type,\r
2382                         hCurrentProcessHandle,\r
2383                         GetCurrentThread(),\r
2384                         &sf,\r
2385                         NULL, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL);\r
2386 #else   // CPU_64\r
2387                 ret = StackWalk64(type,\r
2388                         hCurrentProcessHandle,\r
2389                         GetCurrentThread(),\r
2390                         &sf,\r
2391                         &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL);\r
2392 #endif  // CPU_64\r
2393                 if (ret == false || sf.AddrFrame.Offset == 0)\r
2394                 {\r
2395                         break;\r
2396                 }\r
2397 \r
2398                 if (cs == NULL)\r
2399                 {\r
2400                         cs = OSMemoryAlloc(sizeof(CALLSTACK_DATA));\r
2401                         s = cs;\r
2402                 }\r
2403                 else\r
2404                 {\r
2405                         s->next = OSMemoryAlloc(sizeof(CALLSTACK_DATA));\r
2406                         s = s->next;\r
2407                 }\r
2408                 s->symbol_cache = false;\r
2409                 s->next = NULL;\r
2410                 s->offset = sf.AddrPC.Offset;\r
2411                 s->disp = 0;\r
2412                 s->name = NULL;\r
2413                 s->line = 0;\r
2414                 s->filename[0] = 0;\r
2415         }\r
2416 \r
2417         return cs;\r
2418 #else   // WIN32_NO_DEBUG_HELP_DLL\r
2419         return NULL;\r
2420 #endif  // WIN32_NO_DEBUG_HELP_DLL\r
2421 }\r
2422 \r
2423 // コールスタックからシンボル情報を取得\r
2424 bool Win32GetCallStackSymbolInfo(CALLSTACK_DATA *s)\r
2425 {\r
2426 #ifdef  WIN32_NO_DEBUG_HELP_DLL\r
2427         return false;\r
2428 #else   // WIN32_NO_DEBUG_HELP_DLL\r
2429         UINT64 disp;\r
2430         UINT disp32, len;\r
2431         IMAGEHLP_SYMBOL64 *sym;\r
2432         IMAGEHLP_LINE64 line;\r
2433         char tmp[MAX_PATH];\r
2434         // 引数チェック\r
2435         if (s == NULL)\r
2436         {\r
2437                 return false;\r
2438         }\r
2439 \r
2440         if (s->symbol_cache)\r
2441         {\r
2442                 return true;\r
2443         }\r
2444 \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
2448 \r
2449         if (SymGetSymFromAddr64(hCurrentProcessHandle, s->offset, &disp, sym))\r
2450         {\r
2451                 s->disp = disp;\r
2452                 s->name = OSMemoryAlloc((UINT)strlen(sym->Name) + 1);\r
2453                 lstrcpy(s->name, sym->Name);\r
2454         }\r
2455         else\r
2456         {\r
2457                 s->disp = 0;\r
2458                 s->name = NULL;\r
2459         }\r
2460 \r
2461         Zero(&line, sizeof(line));\r
2462         line.SizeOfStruct = sizeof(line);\r
2463         if (SymGetLineFromAddr64(hCurrentProcessHandle, s->offset, &disp32, &line))\r
2464         {\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
2472         }\r
2473         else\r
2474         {\r
2475                 s->line = 0;\r
2476                 s->filename[0] = 0;\r
2477         }\r
2478 \r
2479         OSMemoryFree(sym);\r
2480 \r
2481         s->symbol_cache = true;\r
2482 \r
2483         return true;\r
2484 #endif  // WIN32_NO_DEBUG_HELP_DLL\r
2485 }\r
2486 \r
2487 // デフォルトの Win32 スレッド\r
2488 DWORD CALLBACK Win32DefaultThreadProc(void *param)\r
2489 {\r
2490         WIN32THREADSTARTUPINFO *info = (WIN32THREADSTARTUPINFO *)param;\r
2491         // 引数チェック\r
2492         if (info == NULL)\r
2493         {\r
2494                 return 0;\r
2495         }\r
2496 \r
2497         Win32InitNewThread();\r
2498 \r
2499         // スレッド関数の呼び出し\r
2500         info->thread_proc(info->thread, info->param);\r
2501 \r
2502         // 参照の解放\r
2503         ReleaseThread(info->thread);\r
2504 \r
2505         Win32MemoryFree(info);\r
2506 \r
2507         FreeOpenSSLThreadState();\r
2508 \r
2509         _endthreadex(0);\r
2510         return 0;\r
2511 }\r
2512 \r
2513 // スレッドの終了を待機\r
2514 bool Win32WaitThread(THREAD *t)\r
2515 {\r
2516         WIN32THREAD *w;\r
2517         // 引数チェック\r
2518         if (t == NULL)\r
2519         {\r
2520                 return false;\r
2521         }\r
2522         w = (WIN32THREAD *)t->pData;\r
2523         if (w == NULL)\r
2524         {\r
2525                 return false;\r
2526         }\r
2527 \r
2528         // スレッドイベントを待機する\r
2529         if (WaitForSingleObject(w->hThread, INFINITE) == WAIT_OBJECT_0)\r
2530         {\r
2531                 // スレッドがシグナル状態になった\r
2532                 return true;\r
2533         }\r
2534 \r
2535         // 待機失敗 (タイムアウト等)\r
2536         return false;\r
2537 }\r
2538 \r
2539 // スレッドの解放\r
2540 void Win32FreeThread(THREAD *t)\r
2541 {\r
2542         WIN32THREAD *w;\r
2543         // 引数チェック\r
2544         if (t == NULL)\r
2545         {\r
2546                 return;\r
2547         }\r
2548         w = (WIN32THREAD *)t->pData;\r
2549         if (w == NULL)\r
2550         {\r
2551                 return;\r
2552         }\r
2553 \r
2554         // ハンドルを閉じる\r
2555         CloseHandle(w->hThread);\r
2556 \r
2557         // メモリ解放\r
2558         Win32MemoryFree(t->pData);\r
2559         t->pData = NULL;\r
2560 }\r
2561 \r
2562 // スレッドの初期化\r
2563 bool Win32InitThread(THREAD *t)\r
2564 {\r
2565         WIN32THREAD *w;\r
2566         HANDLE hThread;\r
2567         DWORD thread_id;\r
2568         WIN32THREADSTARTUPINFO *info;\r
2569         // 引数チェック\r
2570         if (t == NULL)\r
2571         {\r
2572                 return false;\r
2573         }\r
2574         if (t->thread_proc == NULL)\r
2575         {\r
2576                 return false;\r
2577         }\r
2578 \r
2579         // スレッドデータ生成\r
2580         w = Win32MemoryAlloc(sizeof(WIN32THREAD));\r
2581 \r
2582         // 起動情報生成\r
2583         info = Win32MemoryAlloc(sizeof(WIN32THREADSTARTUPINFO));\r
2584         info->param = t->param;\r
2585         info->thread_proc = t->thread_proc;\r
2586         info->thread = t;\r
2587         AddRef(t->ref);\r
2588 \r
2589         // スレッド作成\r
2590         t->pData = w;\r
2591         hThread = (HANDLE)_beginthreadex(NULL, 0, Win32DefaultThreadProc, info, 0, &thread_id);\r
2592         if (hThread == NULL)\r
2593         {\r
2594                 // スレッド作成失敗\r
2595                 t->pData = NULL;\r
2596                 Release(t->ref);\r
2597                 Win32MemoryFree(info);\r
2598                 Win32MemoryFree(w);\r
2599                 return false;\r
2600         }\r
2601 \r
2602         // スレッド情報の保存\r
2603         w->hThread = hThread;\r
2604         w->thread_id = thread_id;\r
2605 \r
2606         return true;\r
2607 }\r
2608 \r
2609 // Win32 用ライブラリの初期化\r
2610 void Win32Init()\r
2611 {\r
2612         INITCOMMONCONTROLSEX c;\r
2613         OSVERSIONINFO os;\r
2614 \r
2615         // Windows NT かどうか取得する\r
2616         Zero(&os, sizeof(os));\r
2617         os.dwOSVersionInfoSize = sizeof(os);\r
2618         GetVersionEx(&os);\r
2619 \r
2620         if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)\r
2621         {\r
2622                 // NT 系\r
2623                 win32_is_nt = true;\r
2624         }\r
2625         else\r
2626         {\r
2627                 // 9x 系\r
2628                 win32_is_nt = false;\r
2629         }\r
2630 \r
2631         // stdout を開く\r
2632         if (hstdout == INVALID_HANDLE_VALUE)\r
2633         {\r
2634                 hstdout = GetStdHandle(STD_OUTPUT_HANDLE);\r
2635         }\r
2636 \r
2637         // stdin を開く\r
2638         if (hstdin == INVALID_HANDLE_VALUE)\r
2639         {\r
2640                 hstdin = GetStdHandle(STD_INPUT_HANDLE);\r
2641         }\r
2642 \r
2643         Win32InitNewThread();\r
2644 \r
2645         CoInitialize(NULL);\r
2646 \r
2647         InitializeCriticalSection(&fasttick_lock);\r
2648 \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
2654 \r
2655         if (MayaquaIsDotNetMode())\r
2656         {\r
2657                 // .NET API 内からヒープ関係の API を呼び出すとクラッシュする\r
2658                 use_heap_api = false;\r
2659         }\r
2660 \r
2661         if (IsNt() == false)\r
2662         {\r
2663                 // Win9x ではヒープ関係の API は使用しない\r
2664                 use_heap_api = false;\r
2665         }\r
2666 \r
2667         if (use_heap_api)\r
2668         {\r
2669                 heap_handle = HeapCreate(0, 0, 0);\r
2670         }\r
2671 \r
2672         // プロセス擬似ハンドルの取得\r
2673         hCurrentProcessHandle = GetCurrentProcess();\r
2674 \r
2675         // カレントディレクトリの初期化\r
2676         // Win32InitCurrentDir(); /* 行わない */\r
2677 \r
2678         // シンボルハンドラの初期化\r
2679         if (IsMemCheck())\r
2680         {\r
2681 #ifndef WIN32_NO_DEBUG_HELP_DLL\r
2682                 SymInitialize(hCurrentProcessHandle, NULL, TRUE);\r
2683 #endif  // WIN32_NO_DEBUG_HELP_DLL\r
2684         }\r
2685 \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
2696 }\r
2697 \r
2698 // Win32 用ライブラリの解放\r
2699 void Win32Free()\r
2700 {\r
2701         // シンボルハンドラを閉じる\r
2702         if (IsMemCheck())\r
2703         {\r
2704 #ifndef WIN32_NO_DEBUG_HELP_DLL\r
2705                 SymCleanup(hCurrentProcessHandle);\r
2706 #endif  // WIN32_NO_DEBUG_HELP_DLL\r
2707         }\r
2708 \r
2709         if (use_heap_api)\r
2710         {\r
2711                 HeapDestroy(heap_handle);\r
2712                 heap_handle = NULL;\r
2713         }\r
2714 \r
2715         CoUninitialize();\r
2716 \r
2717         DeleteCriticalSection(&fasttick_lock);\r
2718 }\r
2719 \r
2720 // メモリ確保\r
2721 void *Win32MemoryAlloc(UINT size)\r
2722 {\r
2723         if (use_heap_api)\r
2724         {\r
2725                 return HeapAlloc(heap_handle, 0, size);\r
2726         }\r
2727         else\r
2728         {\r
2729                 return malloc(size);\r
2730         }\r
2731 }\r
2732 \r
2733 // メモリ再確保\r
2734 void *Win32MemoryReAlloc(void *addr, UINT size)\r
2735 {\r
2736         if (use_heap_api)\r
2737         {\r
2738                 return HeapReAlloc(heap_handle, 0, addr, size);\r
2739         }\r
2740         else\r
2741         {\r
2742                 return realloc(addr, size);\r
2743         }\r
2744 }\r
2745 \r
2746 // メモリ確報\r
2747 void Win32MemoryFree(void *addr)\r
2748 {\r
2749         if (use_heap_api)\r
2750         {\r
2751                 HeapFree(heap_handle, 0, addr);\r
2752         }\r
2753         else\r
2754         {\r
2755                 free(addr);\r
2756         }\r
2757 }\r
2758 \r
2759 // システムタイマの取得\r
2760 UINT Win32GetTick()\r
2761 {\r
2762         return (UINT)timeGetTime();\r
2763 }\r
2764 \r
2765 // システム時刻の取得\r
2766 void Win32GetSystemTime(SYSTEMTIME *system_time)\r
2767 {\r
2768         // システム時刻の取得\r
2769         GetSystemTime(system_time);\r
2770 }\r
2771 \r
2772 // 32bit 整数のインクリメント\r
2773 void Win32Inc32(UINT *value)\r
2774 {\r
2775         InterlockedIncrement(value);\r
2776 }\r
2777 \r
2778 // 32bit 整数のデクリメント\r
2779 void Win32Dec32(UINT *value)\r
2780 {\r
2781         InterlockedDecrement(value);\r
2782 }\r
2783 \r
2784 // スレッドの休止\r
2785 void Win32Sleep(UINT time)\r
2786 {\r
2787         Sleep(time);\r
2788 }\r
2789 \r
2790 // ロックの作成\r
2791 LOCK *Win32NewLock()\r
2792 {\r
2793         // メモリ確保\r
2794         LOCK *lock = Win32MemoryAlloc(sizeof(LOCK));\r
2795 \r
2796         // クリティカルセクション確保\r
2797         CRITICAL_SECTION *critical_section = Win32MemoryAlloc(sizeof(CRITICAL_SECTION));\r
2798 \r
2799         if (lock == NULL || critical_section == NULL)\r
2800         {\r
2801                 Win32MemoryFree(lock);\r
2802                 Win32MemoryFree(critical_section);\r
2803                 return NULL;\r
2804         }\r
2805 \r
2806         // クリティカルセクション初期化\r
2807         InitializeCriticalSection(critical_section);\r
2808 \r
2809         lock->pData = (void *)critical_section;\r
2810         lock->Ready = true;\r
2811 \r
2812         return lock;\r
2813 }\r
2814 \r
2815 // ロック\r
2816 bool Win32Lock(LOCK *lock)\r
2817 {\r
2818         CRITICAL_SECTION *critical_section;\r
2819         if (lock->Ready == false)\r
2820         {\r
2821                 // 状態が不正\r
2822                 return false;\r
2823         }\r
2824 \r
2825         // クリティカルセクションに入る\r
2826         critical_section = (CRITICAL_SECTION *)lock->pData;\r
2827         EnterCriticalSection(critical_section);\r
2828 \r
2829         return true;\r
2830 }\r
2831 \r
2832 // ロック解除\r
2833 void Win32Unlock(LOCK *lock)\r
2834 {\r
2835         Win32UnlockEx(lock, false);\r
2836 }\r
2837 void Win32UnlockEx(LOCK *lock, bool inner)\r
2838 {\r
2839         CRITICAL_SECTION *critical_section;\r
2840         if (lock->Ready == false && inner == false)\r
2841         {\r
2842                 // 状態が不正\r
2843                 return;\r
2844         }\r
2845 \r
2846         // クリティカルセクションから出る\r
2847         critical_section = (CRITICAL_SECTION *)lock->pData;\r
2848         LeaveCriticalSection(critical_section);\r
2849 }\r
2850 \r
2851 // ロックの削除\r
2852 void Win32DeleteLock(LOCK *lock)\r
2853 {\r
2854         CRITICAL_SECTION *critical_section;\r
2855         // Ready フラグを安全に解除する\r
2856         Win32Lock(lock);\r
2857         lock->Ready = false;\r
2858         Win32UnlockEx(lock, true);\r
2859 \r
2860         // クリティカルセクションの削除\r
2861         critical_section = (CRITICAL_SECTION *)lock->pData;\r
2862         DeleteCriticalSection(critical_section);\r
2863 \r
2864         // メモリ解放\r
2865         Win32MemoryFree(critical_section);\r
2866         Win32MemoryFree(lock);\r
2867 }\r
2868 \r
2869 // イベントの初期化\r
2870 void Win32InitEvent(EVENT *event)\r
2871 {\r
2872         // 自動リセットイベントの作成\r
2873         HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\r
2874 \r
2875         event->pData = hEvent;\r
2876 }\r
2877 \r
2878 // イベントのセット\r
2879 void Win32SetEvent(EVENT *event)\r
2880 {\r
2881         HANDLE hEvent = (HANDLE)event->pData;\r
2882         if (hEvent == NULL)\r
2883         {\r
2884                 return;\r
2885         }\r
2886 \r
2887         SetEvent(hEvent);\r
2888 }\r
2889 \r
2890 // イベントのリセット\r
2891 void Win32ResetEvent(EVENT *event)\r
2892 {\r
2893         HANDLE hEvent = (HANDLE)event->pData;\r
2894         if (hEvent == NULL)\r
2895         {\r
2896                 return;\r
2897         }\r
2898 \r
2899         ResetEvent(hEvent);\r
2900 }\r
2901 \r
2902 // イベントを待機する\r
2903 bool Win32WaitEvent(EVENT *event, UINT timeout)\r
2904 {\r
2905         HANDLE hEvent = (HANDLE)event->pData;\r
2906         UINT ret;\r
2907         if (hEvent == NULL)\r
2908         {\r
2909                 return false;\r
2910         }\r
2911 \r
2912         // オブジェクトを待機\r
2913         ret = WaitForSingleObject(hEvent, timeout);\r
2914         if (ret == WAIT_TIMEOUT)\r
2915         {\r
2916                 // タイムアウト\r
2917                 return false;\r
2918         }\r
2919         else\r
2920         {\r
2921                 // シグナル状態\r
2922                 return true;\r
2923         }\r
2924 }\r
2925 \r
2926 // イベントの解放\r
2927 void Win32FreeEvent(EVENT *event)\r
2928 {\r
2929         HANDLE hEvent = (HANDLE)event->pData;\r
2930         if (hEvent == NULL)\r
2931         {\r
2932                 return;\r
2933         }\r
2934 \r
2935         CloseHandle(hEvent);\r
2936 }\r
2937 \r
2938 // Win32 専用の高速な 64 bit Tick 取得関数\r
2939 UINT64 Win32FastTick64()\r
2940 {\r
2941         static UINT last_tick = 0;\r
2942         static UINT counter = 0;\r
2943         UINT64 ret;\r
2944         UINT tick;\r
2945 \r
2946         EnterCriticalSection(&fasttick_lock);\r
2947 \r
2948         // 現在の tick 値を取得する\r
2949         tick = Win32GetTick();\r
2950 \r
2951         if (last_tick > tick)\r
2952         {\r
2953                 // 前回取得した tick 値のほうが今回取得した値よりも大きい場合\r
2954                 // カウンタが 1 回りしたと考えることができる\r
2955 \r
2956                 counter++;\r
2957         }\r
2958 \r
2959         last_tick = tick;\r
2960 \r
2961         ret = (UINT64)tick + (UINT64)counter * 4294967296ULL;\r
2962 \r
2963         LeaveCriticalSection(&fasttick_lock);\r
2964 \r
2965         if (start_tick == 0)\r
2966         {\r
2967                 start_tick = ret;\r
2968                 ret = 0;\r
2969         }\r
2970         else\r
2971         {\r
2972                 ret -= start_tick;\r
2973         }\r
2974 \r
2975         return ret + 1;\r
2976 }\r
2977 \r
2978 // 文字列をコンソールから読み込む\r
2979 bool Win32InputW(wchar_t *str, UINT size)\r
2980 {\r
2981         bool ret = false;\r
2982         // 引数チェック\r
2983         if (str == NULL)\r
2984         {\r
2985                 return false;\r
2986         }\r
2987         if (size == 0)\r
2988         {\r
2989                 size = 0x7fffffff;\r
2990         }\r
2991 \r
2992         if (str == NULL || size <= sizeof(wchar_t))\r
2993         {\r
2994                 if (str != NULL)\r
2995                 {\r
2996                         Zero(str, size);\r
2997                 }\r
2998 \r
2999                 return Win32InputFromFileW(NULL, 0);\r
3000         }\r
3001 \r
3002         if (IsNt())\r
3003         {\r
3004                 DWORD read_size = 0;\r
3005 \r
3006                 if (ReadConsoleW(hstdin, str, (size - sizeof(wchar_t)), &read_size, NULL))\r
3007                 {\r
3008                         str[read_size] = 0;\r
3009 \r
3010                         UniTrimCrlf(str);\r
3011 \r
3012                         ret = true;\r
3013                 }\r
3014                 else\r
3015                 {\r
3016                         ret = Win32InputFromFileW(str, size);\r
3017                 }\r
3018         }\r
3019         else\r
3020         {\r
3021                 DWORD read_size = 0;\r
3022                 UINT a_size = size / sizeof(wchar_t) + 16;\r
3023                 char *a;\r
3024 \r
3025                 a = ZeroMalloc(a_size);\r
3026 \r
3027                 if (ReadConsoleA(hstdin, a, a_size - 1, &read_size, NULL))\r
3028                 {\r
3029                         a[read_size] = 0;\r
3030 \r
3031                         StrToUni(str, size, a);\r
3032 \r
3033                         UniTrimCrlf(str);\r
3034 \r
3035                         ret = true;\r
3036                 }\r
3037                 else\r
3038                 {\r
3039                         ret = Win32InputFromFileW(str, size);\r
3040                 }\r
3041 \r
3042                 Free(a);\r
3043         }\r
3044 \r
3045         return ret;\r
3046 }\r
3047 // 1 行を標準入力から取得\r
3048 bool Win32InputFromFileW(wchar_t *str, UINT size)\r
3049 {\r
3050         char *a;\r
3051         if (str == NULL)\r
3052         {\r
3053                 wchar_t tmp[MAX_SIZE];\r
3054                 Win32InputFromFileW(tmp, sizeof(tmp));\r
3055                 return false;\r
3056         }\r
3057 \r
3058         a = Win32InputFromFileLineA();\r
3059         if (a == NULL)\r
3060         {\r
3061                 UniStrCpy(str, size, L"");\r
3062                 return false;\r
3063         }\r
3064 \r
3065         UtfToUni(str, size, a);\r
3066 \r
3067         UniTrimCrlf(str);\r
3068 \r
3069         Free(a);\r
3070 \r
3071         return true;\r
3072 }\r
3073 char *Win32InputFromFileLineA()\r
3074 {\r
3075         BUF *b = NewBuf();\r
3076         char zero = 0;\r
3077         char *ret = NULL;\r
3078         bool ok = true;\r
3079 \r
3080         while (true)\r
3081         {\r
3082                 char c;\r
3083                 UINT read_size = 0;\r
3084 \r
3085                 if (ReadFile(hstdin, &c, 1, &read_size, NULL) == false)\r
3086                 {\r
3087                         ok = false;\r
3088                         break;\r
3089                 }\r
3090                 if (read_size != 1)\r
3091                 {\r
3092                         ok = false;\r
3093                         break;\r
3094                 }\r
3095 \r
3096                 WriteBuf(b, &c, 1);\r
3097 \r
3098                 if (c == 10)\r
3099                 {\r
3100                         break;\r
3101                 }\r
3102         }\r
3103 \r
3104         WriteBuf(b, &zero, 1);\r
3105 \r
3106         if (ok)\r
3107         {\r
3108                 ret = CopyStr(b->Buf);\r
3109         }\r
3110 \r
3111         FreeBuf(b);\r
3112 \r
3113         return ret;\r
3114 }\r
3115 \r
3116 // 文字列をコンソールにプリントする\r
3117 void Win32PrintW(wchar_t *str)\r
3118 {\r
3119         DWORD write_size = 0;\r
3120         // 引数チェック\r
3121         if (str == NULL)\r
3122         {\r
3123                 return;\r
3124         }\r
3125 \r
3126         if (IsNt())\r
3127         {\r
3128                 if (WriteConsoleW(hstdout, str, UniStrLen(str), &write_size, NULL) == false)\r
3129                 {\r
3130                         Win32PrintToFileW(str);\r
3131                 }\r
3132         }\r
3133         else\r
3134         {\r
3135                 char *ansi_str = CopyUniToStr(str);\r
3136 \r
3137                 if (WriteConsoleA(hstdout, ansi_str, StrLen(ansi_str), &write_size, NULL) == false)\r
3138                 {\r
3139                         Win32PrintToFileW(str);\r
3140                 }\r
3141 \r
3142                 Free(ansi_str);\r
3143         }\r
3144 }\r
3145 void Win32PrintToFileW(wchar_t *str)\r
3146 {\r
3147         char *utf;\r
3148         DWORD size = 0;\r
3149         // 引数チェック\r
3150         if (str == NULL)\r
3151         {\r
3152                 return;\r
3153         }\r
3154 \r
3155         utf = CopyUniToUtf(str);\r
3156 \r
3157         WriteFile(hstdout, utf, StrLen(utf), &size, NULL);\r
3158 \r
3159         Free(utf);\r
3160 }\r
3161 \r
3162 \r
3163 #endif  // WIN32\r
3164 \r
3165 \r