* copy vendor drop to trunk
[lab.git] / Dev / utvpn / utvpn-unix-v101-7101-public / src / Mayaqua / Microsoft.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 // Microsoft.c\r
79 // Microsoft Windows 用コード\r
80 // (Windows 以外の環境ではコンパイルされない)\r
81 \r
82 #ifdef  WIN32\r
83 \r
84 #define MICROSOFT_C\r
85 \r
86 typedef enum    _PNP_VETO_TYPE {\r
87     PNP_VetoTypeUnknown,            // Name is unspecified\r
88     PNP_VetoLegacyDevice,           // Name is an Instance Path\r
89     PNP_VetoPendingClose,           // Name is an Instance Path\r
90     PNP_VetoWindowsApp,             // Name is a Module\r
91     PNP_VetoWindowsService,         // Name is a Service\r
92     PNP_VetoOutstandingOpen,        // Name is an Instance Path\r
93     PNP_VetoDevice,                 // Name is an Instance Path\r
94     PNP_VetoDriver,                 // Name is a Driver Service Name\r
95     PNP_VetoIllegalDeviceRequest,   // Name is an Instance Path\r
96     PNP_VetoInsufficientPower,      // Name is unspecified\r
97     PNP_VetoNonDisableable,         // Name is an Instance Path\r
98     PNP_VetoLegacyDriver,           // Name is a Service\r
99     PNP_VetoInsufficientRights      // Name is unspecified\r
100 }   PNP_VETO_TYPE, *PPNP_VETO_TYPE;\r
101 \r
102 #define _WIN32_IE                       0x0600\r
103 #define _WIN32_WINNT            0x0502\r
104 #define WINVER                          0x0502\r
105 #define   SECURITY_WIN32\r
106 #include <winsock2.h>\r
107 #include <windows.h>\r
108 #include <Wintrust.h>\r
109 #include <Softpub.h>\r
110 #include <Iphlpapi.h>\r
111 #include <tlhelp32.h>\r
112 #include <wincon.h>\r
113 #include <Nb30.h>\r
114 #include <shlobj.h>\r
115 #include <commctrl.h>\r
116 #include <Dbghelp.h>\r
117 #include <setupapi.h>\r
118 #include <regstr.h>\r
119 #include <process.h>\r
120 #include <psapi.h>\r
121 #include <wtsapi32.h>\r
122 #include <security.h>\r
123 #include <stdio.h>\r
124 #include <stdlib.h>\r
125 #include <string.h>\r
126 #include <wchar.h>\r
127 #include <stdarg.h>\r
128 #include <time.h>\r
129 #include <errno.h>\r
130 #include <Mayaqua/Mayaqua.h>\r
131 #include <cfgmgr32.h>\r
132 #include <sddl.h>\r
133 #include <Aclapi.h>\r
134 \r
135 \r
136 static MS *ms = NULL;\r
137 \r
138 // 関数プロトタイプ\r
139 UINT MsgBox(HWND hWnd, UINT flag, wchar_t *msg);\r
140 UINT MsgBoxEx(HWND hWnd, UINT flag, wchar_t *msg, ...);\r
141 void ShowTcpIpConfigUtil(HWND hWnd, bool util_mode);\r
142 void CmTraffic(HWND hWnd);\r
143 void CnStart();\r
144 void InitCedar();\r
145 void FreeCedar();\r
146 void InitWinUi(wchar_t *software_name, char *font, UINT fontsize);\r
147 void FreeWinUi();\r
148 \r
149 // グローバル変数\r
150 void *ms_critical_section = NULL;\r
151 UINT64 ms_uint64_1 = 0;\r
152 \r
153 // アダプタリスト関係\r
154 static LOCK *lock_adapter_list = NULL;\r
155 static MS_ADAPTER_LIST *last_adapter_list = NULL;\r
156 \r
157 // サービス関係\r
158 static SERVICE_STATUS_HANDLE ssh = NULL;\r
159 static SERVICE_STATUS status;\r
160 static char g_service_name[MAX_SIZE];\r
161 static SERVICE_FUNCTION *g_start, *g_stop;\r
162 static bool exiting = false;\r
163 static bool wnd_end;\r
164 static bool is_usermode = false;\r
165 static HICON tray_icon;\r
166 static NOTIFYICONDATA nid;\r
167 static NOTIFYICONDATAW nid_nt;\r
168 static bool service_for_9x_mode = false;\r
169 static THREAD *starter_thread = NULL;\r
170 static EVENT *server_stopped_event = NULL;\r
171 static THREAD *service_stopper_thread = NULL;\r
172 static bool tray_inited = false;\r
173 static HWND hWndUsermode = NULL;\r
174 \r
175 // [ネットワーク接続] を開くためのショートカット (最新版では未使用)\r
176 static UCHAR network_connection_link[] =\r
177 {\r
178         0x4C, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, \r
179         0x00, 0x00, 0x00, 0x46, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
180         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
181         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, \r
182         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x14, 0x00, \r
183         0x1F, 0x50, 0xE0, 0x4F, 0xD0, 0x20, 0xEA, 0x3A, 0x69, 0x10, 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, \r
184         0x30, 0x9D, 0x14, 0x00, 0x2E, 0x00, 0x20, 0x20, 0xEC, 0x21, 0xEA, 0x3A, 0x69, 0x10, 0xA2, 0xDD, \r
185         0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D, 0x14, 0x00, 0x70, 0x00, 0xC7, 0xAC, 0x07, 0x70, 0x02, 0x32, \r
186         0xD1, 0x11, 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
187 };\r
188 \r
189 // Windows Vista 関係の新しいセキュリティ構造体等\r
190 #if     0\r
191 typedef struct _TOKEN_MANDATORY_LABEL\r
192 {\r
193         SID_AND_ATTRIBUTES Label;\r
194 } TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;\r
195 #endif\r
196 \r
197 #define SE_GROUP_INTEGRITY                 (0x00000020L)\r
198 \r
199 typedef enum _TOKEN_INFORMATION_CLASS_VISTA\r
200 {\r
201         VistaTokenUser = 1,\r
202         VistaTokenGroups,\r
203         VistaTokenPrivileges,\r
204         VistaTokenOwner,\r
205         VistaTokenPrimaryGroup,\r
206         VistaTokenDefaultDacl,\r
207         VistaTokenSource,\r
208         VistaTokenType,\r
209         VistaTokenImpersonationLevel,\r
210         VistaTokenStatistics,\r
211         VistaTokenRestrictedSids,\r
212         VistaTokenSessionId,\r
213         VistaTokenGroupsAndPrivileges,\r
214         VistaTokenSessionReference,\r
215         VistaTokenSandBoxInert,\r
216         VistaTokenAuditPolicy,\r
217         VistaTokenOrigin,\r
218         VistaTokenElevationType,\r
219         VistaTokenLinkedToken,\r
220         VistaTokenElevation,\r
221         VistaTokenHasRestrictions,\r
222         VistaTokenAccessInformation,\r
223         VistaTokenVirtualizationAllowed,\r
224         VistaTokenVirtualizationEnabled,\r
225         VistaTokenIntegrityLevel,\r
226         VistaTokenUIAccess,\r
227         VistaTokenMandatoryPolicy,\r
228         VistaTokenLogonSid,\r
229         VistaMaxTokenInfoClass\r
230 } TOKEN_INFORMATION_CLASS_VISTA, *PTOKEN_INFORMATION_CLASS_VISTA;\r
231 \r
232 // エラーを表示しないモードにする\r
233 void MsSetErrorModeToSilent()\r
234 {\r
235         SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);\r
236 }\r
237 \r
238 // ファイル情報の取得\r
239 bool MsGetFileInformation(void *h, void *info)\r
240 {\r
241         // 引数チェック\r
242         if (h == INVALID_HANDLE_VALUE || info == NULL)\r
243         {\r
244                 return false;\r
245         }\r
246 \r
247         if (MsIsNt() == false)\r
248         {\r
249                 return false;\r
250         }\r
251 \r
252         if (ms->nt->GetFileInformationByHandle == NULL)\r
253         {\r
254                 return false;\r
255         }\r
256 \r
257         return ms->nt->GetFileInformationByHandle(h, info);\r
258 }\r
259 \r
260 // プロセスのシャットダウンパラメータの設定\r
261 void MsSetShutdownParameters(UINT level, UINT flag)\r
262 {\r
263         if (MsIsNt() == false)\r
264         {\r
265                 return;\r
266         }\r
267 \r
268         if (ms->nt == false || ms->nt->SetProcessShutdownParameters == NULL)\r
269         {\r
270                 return;\r
271         }\r
272 \r
273         ms->nt->SetProcessShutdownParameters(level, flag);\r
274 }\r
275 \r
276 // OS のバージョンが Windows XP または Windows Vista 以降かどうか取得する\r
277 bool MsIsWinXPOrWinVista()\r
278 {\r
279         OS_INFO *info = GetOsInfo();\r
280         if (info == NULL)\r
281         {\r
282                 return false;\r
283         }\r
284 \r
285         if (OS_IS_WINDOWS_NT(info->OsType) == false)\r
286         {\r
287                 return false;\r
288         }\r
289 \r
290         if (GET_KETA(info->OsType, 100) >= 3)\r
291         {\r
292                 return true;\r
293         }\r
294 \r
295         return false;\r
296 }\r
297 \r
298 // イベントログに書き込む\r
299 bool MsWriteEventLog(void *p, UINT type, wchar_t *str)\r
300 {\r
301         MS_EVENTLOG *g = (MS_EVENTLOG *)p;\r
302         wchar_t *strings[2];\r
303         UINT id = 0;\r
304         UINT typeapi = 0;\r
305         // 引数チェック\r
306         if (g == NULL || type >= 5 || str == NULL)\r
307         {\r
308                 return false;\r
309         }\r
310 \r
311         strings[0] = str;\r
312 \r
313         switch (type)\r
314         {\r
315         case MS_EVENTLOG_TYPE_INFORMATION:\r
316                 id = MS_RC_EVENTLOG_TYPE_INFORMATION;\r
317                 typeapi = EVENTLOG_INFORMATION_TYPE;\r
318                 break;\r
319 \r
320         case MS_EVENTLOG_TYPE_WARNING:\r
321                 id = MS_RC_EVENTLOG_TYPE_WARNING;\r
322                 typeapi = EVENTLOG_WARNING_TYPE;\r
323                 break;\r
324 \r
325         case MS_EVENTLOG_TYPE_ERROR:\r
326                 id = MS_RC_EVENTLOG_TYPE_ERROR;\r
327                 typeapi = EVENTLOG_ERROR_TYPE;\r
328                 break;\r
329         }\r
330 \r
331         return ms->nt->ReportEventW(g->hEventLog, typeapi, 0, id, NULL, 1, 0, strings, NULL);\r
332 }\r
333 \r
334 // イベントログの解放\r
335 void MsFreeEventLog(void *p)\r
336 {\r
337         MS_EVENTLOG *g = (MS_EVENTLOG *)p;\r
338         // 引数チェック\r
339         if (g == NULL)\r
340         {\r
341                 return;\r
342         }\r
343 \r
344         ms->nt->DeregisterEventSource(g->hEventLog);\r
345 \r
346         Free(g);\r
347 }\r
348 \r
349 // イベントログの初期化\r
350 void *MsInitEventLog(wchar_t *src_name)\r
351 {\r
352         MS_EVENTLOG *g;\r
353         HANDLE h;\r
354         wchar_t keyname[MAX_PATH];\r
355         char keyname_a[MAX_PATH];\r
356         wchar_t *exename;\r
357         // 引数チェック\r
358         if (src_name == NULL)\r
359         {\r
360                 return NULL;\r
361         }\r
362 \r
363         // レジストリにキーを書き込む\r
364         exename = MsGetExeFileNameW();\r
365         UniFormat(keyname, sizeof(keyname),\r
366                 L"SYSTEM\\CurrentControlSet\\Services\\Eventlog\\Application\\%s",\r
367                 src_name);\r
368         UniToStr(keyname_a, sizeof(keyname_a), keyname);\r
369 \r
370         MsRegWriteStrExpandExW(REG_LOCAL_MACHINE, keyname_a, "EventMessageFile",\r
371                 exename, false);\r
372 \r
373         MsRegWriteIntEx(REG_LOCAL_MACHINE, keyname_a, "TypesSupported", 7, false);\r
374 \r
375         h = ms->nt->RegisterEventSourceW(NULL, src_name);\r
376         if (h == NULL)\r
377         {\r
378                 return NULL;\r
379         }\r
380 \r
381         g = ZeroMalloc(sizeof(MS_EVENTLOG));\r
382 \r
383         g->hEventLog = h;\r
384 \r
385         return (void *)g;\r
386 }\r
387 \r
388 // クリップボードを空にする\r
389 void MsDeleteClipboard()\r
390 {\r
391         OpenClipboard(NULL);\r
392 \r
393         EmptyClipboard();\r
394 \r
395         CloseClipboard();\r
396 }\r
397 \r
398 // クリップボード所有者のプロセス ID を取得する\r
399 UINT MsGetClipboardOwnerProcessId()\r
400 {\r
401         HWND hWnd = GetClipboardOwner();\r
402         DWORD pid = 0;\r
403 \r
404         if (hWnd == NULL)\r
405         {\r
406                 return 0;\r
407         }\r
408 \r
409         GetWindowThreadProcessId(hWnd, &pid);\r
410 \r
411         return pid;\r
412 }\r
413 \r
414 // MMCSS の再起動\r
415 // 注意: この実装は完璧ではない。\r
416 void MsRestartMMCSS()\r
417 {\r
418         MsStopService("CTAudSvcService");\r
419         MsStopService("audiosrv");\r
420         MsStopService("MMCSS");\r
421         MsStartService("MMCSS");\r
422         MsStartService("audiosrv");\r
423         MsStartService("CTAudSvcService");\r
424 }\r
425 \r
426 // MMCSS によるネットワークスロットリングを有効 / 無効にする\r
427 void MsSetMMCSSNetworkThrottlingEnable(bool enable)\r
428 {\r
429         UINT value;\r
430         if (MsIsVista() == false)\r
431         {\r
432                 return;\r
433         }\r
434 \r
435         if (enable)\r
436         {\r
437                 value = 0x0000000a;\r
438         }\r
439         else\r
440         {\r
441                 value = 0xffffffff;\r
442         }\r
443 \r
444         MsRegWriteIntEx2(REG_LOCAL_MACHINE, MMCSS_PROFILE_KEYNAME, "NetworkThrottlingIndex",\r
445                 value,\r
446                 false, true);\r
447 \r
448         MsRestartMMCSS();\r
449 }\r
450 \r
451 // MMCSS によるネットワークスロットリングが有効になっているかどうか調査\r
452 bool MsIsMMCSSNetworkThrottlingEnabled()\r
453 {\r
454         UINT value;\r
455         if (MsIsVista() == false)\r
456         {\r
457                 return false;\r
458         }\r
459 \r
460         if (MsRegIsKeyEx2(REG_LOCAL_MACHINE, MMCSS_PROFILE_KEYNAME, false, true) == false)\r
461         {\r
462                 return false;\r
463         }\r
464 \r
465         value = MsRegReadIntEx2(REG_LOCAL_MACHINE, MMCSS_PROFILE_KEYNAME,\r
466                 "NetworkThrottlingIndex", false, true);\r
467 \r
468         if (value == 0)\r
469         {\r
470                 return false;\r
471         }\r
472 \r
473         if (value == 0x0000000a)\r
474         {\r
475                 return true;\r
476         }\r
477 \r
478         return false;\r
479 }\r
480 \r
481 // サブキーをすべて削除する\r
482 void MsRegDeleteSubkeys(UINT root, char *keyname, bool force32bit, bool force64bit)\r
483 {\r
484         TOKEN_LIST *t;\r
485         UINT i;\r
486         // 引数チェック\r
487         if (keyname == NULL)\r
488         {\r
489                 return;\r
490         }\r
491 \r
492         t = MsRegEnumKeyEx2(root, keyname, force32bit, force64bit);\r
493         if (t == NULL)\r
494         {\r
495                 return;\r
496         }\r
497 \r
498         for (i = 0;i < t->NumTokens;i++)\r
499         {\r
500                 char tmp[MAX_PATH];\r
501 \r
502                 Format(tmp, sizeof(tmp), "%s\\%s", keyname, t->Token[i]);\r
503 \r
504                 MsRegDeleteKeyEx2(root, tmp, force32bit, force64bit);\r
505         }\r
506 \r
507         FreeToken(t);\r
508 }\r
509 \r
510 // バッファのデータをレジストリのサブキーに変換する\r
511 void MsBufToRegSubkeys(UINT root, char *keyname, BUF *b, bool overwrite, bool force32bit, bool force64bit)\r
512 {\r
513         UINT i;\r
514         UINT a;\r
515         UINT num_keys;\r
516         // 引数チェック\r
517         if (keyname == NULL || b == NULL)\r
518         {\r
519                 return;\r
520         }\r
521 \r
522         SeekBuf(b, 0, 0);\r
523 \r
524         num_keys = ReadBufInt(b);\r
525 \r
526         for (i = 0;i < num_keys;i++)\r
527         {\r
528                 char subkeyname[MAX_PATH];\r
529                 char fullkeyname[MAX_PATH];\r
530                 UINT j;\r
531                 UINT num_values;\r
532 \r
533                 Zero(subkeyname, sizeof(subkeyname));\r
534                 ReadBufStr(b, subkeyname, sizeof(subkeyname));\r
535 \r
536                 Format(fullkeyname, sizeof(fullkeyname), "%s\\%s", keyname, subkeyname);\r
537 \r
538                 num_values = ReadBufInt(b);\r
539 \r
540                 for (j = 0;j < num_values;j++)\r
541                 {\r
542                         char valuename[MAX_PATH];\r
543                         char data[MAX_SIZE];\r
544 \r
545                         Zero(valuename, sizeof(valuename));\r
546                         ReadBufStr(b, valuename, sizeof(valuename));\r
547 \r
548                         a = ReadBufInt(b);\r
549 \r
550                         if (a == 0)\r
551                         {\r
552                                 Zero(data, sizeof(data));\r
553                                 ReadBufStr(b, data, sizeof(data));\r
554 \r
555                                 if (overwrite || MsRegIsValueEx2(root, fullkeyname, valuename, force32bit, force64bit) == false)\r
556                                 {\r
557                                         MsRegWriteStrEx2(root, fullkeyname, valuename, data, force32bit, force64bit);\r
558                                 }\r
559                         }\r
560                         else\r
561                         {\r
562                                 if (overwrite || MsRegIsValueEx2(root, fullkeyname, valuename, force32bit, force64bit) == false)\r
563                                 {\r
564                                         MsRegWriteIntEx2(root, fullkeyname, valuename, ReadBufInt(b), force32bit, force64bit);\r
565                                 }\r
566                         }\r
567                 }\r
568         }\r
569 }\r
570 \r
571 // レジストリのサブキーのデータをバッファに変換する\r
572 BUF *MsRegSubkeysToBuf(UINT root, char *keyname, bool force32bit, bool force64bit)\r
573 {\r
574         TOKEN_LIST *t;\r
575         UINT i;\r
576         BUF *b;\r
577         // 引数チェック\r
578         if (keyname == NULL)\r
579         {\r
580                 return NULL;\r
581         }\r
582 \r
583         t = MsRegEnumKeyEx2(root, keyname, force32bit, force64bit);\r
584 \r
585         if (t == NULL)\r
586         {\r
587                 return NULL;\r
588         }\r
589 \r
590         b = NewBuf();\r
591 \r
592         WriteBufInt(b, t->NumTokens);\r
593 \r
594         for (i = 0;i < t->NumTokens;i++)\r
595         {\r
596                 char *name = t->Token[i];\r
597                 char tmp[MAX_PATH];\r
598                 TOKEN_LIST *v;\r
599 \r
600                 Format(tmp, sizeof(tmp), "%s\\%s", keyname, name);\r
601 \r
602                 WriteBufStr(b, name);\r
603 \r
604                 v = MsRegEnumValueEx2(root, tmp, force32bit, force64bit);\r
605                 if (v == NULL)\r
606                 {\r
607                         WriteBufInt(b, 0);\r
608                 }\r
609                 else\r
610                 {\r
611                         UINT j;\r
612 \r
613                         WriteBufInt(b, v->NumTokens);\r
614 \r
615                         for (j = 0;j < v->NumTokens;j++)\r
616                         {\r
617                                 char *valuename = v->Token[j];\r
618                                 char *str;\r
619 \r
620                                 WriteBufStr(b, valuename);\r
621 \r
622                                 str = MsRegReadStrEx2(root, tmp, valuename, force32bit, force64bit);\r
623                                 if (str != NULL)\r
624                                 {\r
625                                         WriteBufInt(b, 0);\r
626                                         WriteBufStr(b, str);\r
627                                         Free(str);\r
628                                 }\r
629                                 else\r
630                                 {\r
631                                         WriteBufInt(b, 1);\r
632                                         WriteBufInt(b, MsRegReadIntEx2(root, tmp, valuename, force32bit, force64bit));\r
633                                 }\r
634                         }\r
635 \r
636                         FreeToken(v);\r
637                 }\r
638         }\r
639 \r
640         FreeToken(t);\r
641 \r
642         return b;\r
643 }\r
644 \r
645 // 指定した EXE ファイル名のプロセスが存在しているかどうかチェック\r
646 bool MsIsProcessExists(char *exename)\r
647 {\r
648         LIST *o;\r
649         bool ret = false;\r
650         UINT i;\r
651         // 引数チェック\r
652         if (exename == NULL)\r
653         {\r
654                 return false;\r
655         }\r
656 \r
657         o = MsGetProcessList();\r
658 \r
659         for (i = 0;i < LIST_NUM(o);i++)\r
660         {\r
661                 MS_PROCESS *proc = LIST_DATA(o, i);\r
662                 char exe[MAX_PATH];\r
663 \r
664                 GetFileNameFromFilePath(exe, sizeof(exe), proc->ExeFilename);\r
665 \r
666                 if (StrCmpi(exename, exe) == 0)\r
667                 {\r
668                         ret = true;\r
669                         break;\r
670                 }\r
671         }\r
672 \r
673         MsFreeProcessList(o);\r
674 \r
675         return ret;\r
676 }\r
677 bool MsIsProcessExistsW(wchar_t *exename)\r
678 {\r
679         LIST *o;\r
680         bool ret = false;\r
681         UINT i;\r
682         // 引数チェック\r
683         if (exename == NULL)\r
684         {\r
685                 return false;\r
686         }\r
687 \r
688         o = MsGetProcessList();\r
689 \r
690         for (i = 0;i < LIST_NUM(o);i++)\r
691         {\r
692                 MS_PROCESS *proc = LIST_DATA(o, i);\r
693                 wchar_t exe[MAX_PATH];\r
694 \r
695                 GetFileNameFromFilePathW(exe, sizeof(exe), proc->ExeFilenameW);\r
696 \r
697                 if (UniStrCmpi(exename, exe) == 0)\r
698                 {\r
699                         ret = true;\r
700                         break;\r
701                 }\r
702         }\r
703 \r
704         MsFreeProcessList(o);\r
705 \r
706         return ret;\r
707 }\r
708 \r
709 typedef struct _ASTAT_\r
710 {\r
711         ADAPTER_STATUS adapt;\r
712         NAME_BUFFER    NameBuff[30];\r
713 } ASTAT, *PASTAT;\r
714 \r
715 // 高精度カウンタの値から精密な時間を取得する\r
716 double MsGetHiResTimeSpan(UINT64 diff)\r
717 {\r
718         LARGE_INTEGER t;\r
719         UINT64 freq;\r
720 \r
721         if (QueryPerformanceFrequency(&t) == false)\r
722         {\r
723                 freq = 1000ULL;\r
724         }\r
725         else\r
726         {\r
727                 Copy(&freq, &t, sizeof(UINT64));\r
728         }\r
729 \r
730         return (double)diff / (double)freq;\r
731 }\r
732 UINT64 MsGetHiResTimeSpanUSec(UINT64 diff)\r
733 {\r
734         LARGE_INTEGER t;\r
735         UINT64 freq;\r
736 \r
737         if (QueryPerformanceFrequency(&t) == false)\r
738         {\r
739                 freq = 1000ULL;\r
740         }\r
741         else\r
742         {\r
743                 Copy(&freq, &t, sizeof(UINT64));\r
744         }\r
745 \r
746         return (UINT64)(diff) * 1000ULL * 1000ULL / (UINT64)freq;\r
747 }\r
748 \r
749 // 高精度カウンタを取得する\r
750 UINT64 MsGetHiResCounter()\r
751 {\r
752         LARGE_INTEGER t;\r
753         UINT64 ret;\r
754 \r
755         if (QueryPerformanceCounter(&t) == false)\r
756         {\r
757                 return Tick64();\r
758         }\r
759 \r
760         Copy(&ret, &t, sizeof(UINT64));\r
761 \r
762         return ret;\r
763 }\r
764 \r
765 // ようこそ画面を使用しているかどうか\r
766 bool MsIsUseWelcomeLogin()\r
767 {\r
768         UINT os_type;\r
769         if (MsIsNt() == false)\r
770         {\r
771                 return false;\r
772         }\r
773 \r
774         os_type = GetOsInfo()->OsType;\r
775 \r
776         if (OS_IS_WINDOWS_NT(os_type))\r
777         {\r
778                 if (GET_KETA(os_type, 100) == 3)\r
779                 {\r
780                         if (MsRegReadIntEx2(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",\r
781                                 "LogonType", false, true) == 0)\r
782                         {\r
783                                 return false;\r
784                         }\r
785                         else\r
786                         {\r
787                                 return true;\r
788                         }\r
789                 }\r
790         }\r
791 \r
792         return false;\r
793 }\r
794 \r
795 // コンピュータの物理的な MAC アドレスを 1 つ取得する\r
796 bool MsGetPhysicalMacAddress(void *address)\r
797 {\r
798         // 引数チェック\r
799         if (address == NULL)\r
800         {\r
801                 return false;\r
802         }\r
803 \r
804         if (MsGetPhysicalMacAddressFromApi(address))\r
805         {\r
806                 return true;\r
807         }\r
808 \r
809         if (MsGetPhysicalMacAddressFromNetbios(address))\r
810         {\r
811                 return true;\r
812         }\r
813 \r
814         return false;\r
815 }\r
816 \r
817 // 物理的な MAC アドレスを取得する (API から)\r
818 bool MsGetPhysicalMacAddressFromApi(void *address)\r
819 {\r
820         MS_ADAPTER_LIST *o;\r
821         UINT i;\r
822         bool ret = false;\r
823         // 引数チェック\r
824         if (address == NULL)\r
825         {\r
826                 return false;\r
827         }\r
828 \r
829         Zero(address, 6);\r
830 \r
831         o = MsCreateAdapterList();\r
832 \r
833         for (i = 0;i < o->Num;i++)\r
834         {\r
835                 MS_ADAPTER *a = o->Adapters[i];\r
836 \r
837                 if (a->AddressSize == 6 && a->Mtu == 1500)\r
838                 {\r
839                         bool b = false;\r
840                         switch (a->Type)\r
841                         {\r
842                         case MIB_IF_TYPE_OTHER:\r
843                         case MIB_IF_TYPE_ETHERNET:\r
844                                 b = true;\r
845                                 break;\r
846 \r
847                         case MIB_IF_TYPE_TOKENRING:\r
848                         case MIB_IF_TYPE_FDDI:\r
849                         case MIB_IF_TYPE_PPP:\r
850                         case MIB_IF_TYPE_LOOPBACK:\r
851                         case MIB_IF_TYPE_SLIP:\r
852                                 b = false;\r
853                                 break;\r
854 \r
855                         default:\r
856                                 b = true;\r
857                                 break;\r
858                         }\r
859 \r
860                         if (b)\r
861                         {\r
862                                 if (SearchStrEx(a->Title, "WAN", 0, false) == INFINITE)\r
863                                 {\r
864                                         if (a->Status == MIB_IF_OPER_STATUS_CONNECTED || a->Status == MIB_IF_OPER_STATUS_OPERATIONAL)\r
865                                         {\r
866                                                 if (a->AddressSize == 6)\r
867                                                 {\r
868                                                         if (IsZero(a->Address, 6) == false)\r
869                                                         {\r
870                                                                 if (Cmp(address, a->Address, 6) <= 0)\r
871                                                                 {\r
872                                                                         Copy(address, a->Address, 6);\r
873                                                                         ret = true;\r
874                                                                 }\r
875                                                         }\r
876                                                 }\r
877                                         }\r
878                                 }\r
879                         }\r
880                 }\r
881         }\r
882 \r
883         MsFreeAdapterList(o);\r
884 \r
885         return ret;\r
886 }\r
887 \r
888 // 物理的な MAC アドレスを取得する (NetBIOS から)\r
889 bool MsGetPhysicalMacAddressFromNetbios(void *address)\r
890 {\r
891         NCB ncb;\r
892         UCHAR ret;\r
893         LANA_ENUM lenum;\r
894         UINT i;\r
895         ASTAT adapter;\r
896         bool b = false;\r
897         // 引数チェック\r
898         if (address == NULL)\r
899         {\r
900                 return false;\r
901         }\r
902 \r
903         Zero(&ncb, sizeof(ncb));\r
904         Zero(&lenum, sizeof(lenum));\r
905 \r
906         ncb.ncb_command = NCBENUM;\r
907         ncb.ncb_buffer = (UCHAR *)&lenum;\r
908         ncb.ncb_length = sizeof(lenum);\r
909         ret = Netbios(&ncb);\r
910 \r
911         Zero(address, 6);\r
912 \r
913         for (i = 0;i < lenum.length;i++)\r
914         {\r
915                 Zero(&ncb, sizeof(ncb));\r
916                 ncb.ncb_command = NCBRESET;\r
917                 ncb.ncb_lana_num = lenum.lana[i];\r
918 \r
919                 ret = Netbios(&ncb);\r
920 \r
921                 Zero(&ncb, sizeof(ncb));\r
922                 ncb.ncb_command = NCBASTAT;\r
923                 ncb.ncb_lana_num = lenum.lana[i];\r
924 \r
925                 StrCpy(ncb.ncb_callname, sizeof(ncb.ncb_callname), "*               ");\r
926                 Zero(&adapter, sizeof(adapter));\r
927                 ncb.ncb_buffer = (char *)&adapter;\r
928                 ncb.ncb_length = sizeof(adapter);\r
929 \r
930                 ret = Netbios(&ncb);\r
931 \r
932                 if (ret == 0)\r
933                 {\r
934                         if (Cmp(address, adapter.adapt.adapter_address, 6) <= 0)\r
935                         {\r
936                                 Copy(address, adapter.adapt.adapter_address, 6);\r
937                                 b = true;\r
938                         }\r
939                 }\r
940         }\r
941 \r
942         return b;\r
943 }\r
944 \r
945 // システム全体のアップデート通知\r
946 void MsUpdateSystem()\r
947 {\r
948         static DWORD dw = 0;\r
949 \r
950         SendMessageTimeoutA(HWND_BROADCAST, WM_WININICHANGE, 0, 0, SMTO_NORMAL, 1, (PDWORD_PTR)&dw);\r
951 }\r
952 \r
953 // 指定されたパスがローカルドライブかどうか取得する\r
954 bool MsIsLocalDrive(char *name)\r
955 {\r
956         char tmp[MAX_PATH];\r
957         UINT ret;\r
958 \r
959         // 引数チェック\r
960         if (name == NULL)\r
961         {\r
962                 return false;\r
963         }\r
964 \r
965         Zero(tmp, sizeof(tmp));\r
966         InnerFilePath(tmp, sizeof(tmp), name);\r
967 \r
968         if (StartWith(tmp, "\\\\"))\r
969         {\r
970                 // ネットワークディレクトリ\r
971                 return false;\r
972         }\r
973 \r
974         if (tmp[1] != ':' || tmp[2] != '\\')\r
975         {\r
976                 // ドライブ名でない\r
977                 return false;\r
978         }\r
979 \r
980         tmp[3] = 0;\r
981 \r
982         ret = GetDriveType(tmp);\r
983 \r
984         if (ret == DRIVE_REMOTE || ret == DRIVE_CDROM || ret == DRIVE_RAMDISK)\r
985         {\r
986                 return false;\r
987         }\r
988 \r
989         return true;\r
990 }\r
991 bool MsIsLocalDriveW(wchar_t *name)\r
992 {\r
993         char name_a[MAX_PATH];\r
994 \r
995         UniToStr(name_a, sizeof(name_a), name);\r
996 \r
997         return MsIsLocalDrive(name_a);\r
998 }\r
999 \r
1000 // 指定されたファイルがロックされているかどうか取得する\r
1001 bool MsIsFileLocked(char *name)\r
1002 {\r
1003         HANDLE h;\r
1004         char tmp[MAX_PATH];\r
1005         // 引数チェック\r
1006         if (name == NULL)\r
1007         {\r
1008                 return false;\r
1009         }\r
1010 \r
1011         InnerFilePath(tmp, sizeof(tmp), name);\r
1012 \r
1013         h = CreateFile(tmp, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);\r
1014         if (h == INVALID_HANDLE_VALUE)\r
1015         {\r
1016                 return true;\r
1017         }\r
1018 \r
1019         CloseHandle(h);\r
1020 \r
1021         return false;\r
1022 }\r
1023 bool MsIsFileLockedW(wchar_t *name)\r
1024 {\r
1025         HANDLE h;\r
1026         wchar_t tmp[MAX_PATH];\r
1027         // 引数チェック\r
1028         if (name == NULL)\r
1029         {\r
1030                 return false;\r
1031         }\r
1032 \r
1033         if (IsNt() == false)\r
1034         {\r
1035                 char name_a[MAX_SIZE];\r
1036 \r
1037                 UniToStr(name_a, sizeof(name_a), name);\r
1038 \r
1039                 return MsIsFileLocked(name_a);\r
1040         }\r
1041 \r
1042         InnerFilePathW(tmp, sizeof(tmp), name);\r
1043 \r
1044         h = CreateFileW(tmp, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);\r
1045         if (h == INVALID_HANDLE_VALUE)\r
1046         {\r
1047                 return true;\r
1048         }\r
1049 \r
1050         CloseHandle(h);\r
1051 \r
1052         return false;\r
1053 }\r
1054 \r
1055 // プロセスの終了を待機\r
1056 UINT MsWaitProcessExit(void *process_handle)\r
1057 {\r
1058         HANDLE h = (HANDLE)process_handle;\r
1059         UINT ret = 1;\r
1060 \r
1061         if (h == NULL)\r
1062         {\r
1063                 return 1;\r
1064         }\r
1065 \r
1066         while (true)\r
1067         {\r
1068                 WaitForSingleObject(h, INFINITE);\r
1069 \r
1070                 ret = 1;\r
1071                 if (GetExitCodeProcess(h, &ret) == false)\r
1072                 {\r
1073                         break;\r
1074                 }\r
1075 \r
1076                 if (ret != STILL_ACTIVE)\r
1077                 {\r
1078                         break;\r
1079                 }\r
1080         }\r
1081 \r
1082         CloseHandle(h);\r
1083 \r
1084         return ret;\r
1085 }\r
1086 \r
1087 // ファイルの実行 (プロセスハンドル取得)\r
1088 bool MsExecuteEx(char *exe, char *arg, void **process_handle)\r
1089 {\r
1090         SHELLEXECUTEINFO info;\r
1091         HANDLE h;\r
1092         // 引数チェック\r
1093         if (exe == NULL || process_handle == NULL)\r
1094         {\r
1095                 return false;\r
1096         }\r
1097 \r
1098         Zero(&info, sizeof(info));\r
1099         info.cbSize = sizeof(info);\r
1100         info.lpVerb = "open";\r
1101         info.lpFile = exe;\r
1102         info.fMask = SEE_MASK_NOCLOSEPROCESS;\r
1103         info.lpParameters = arg;\r
1104         info.nShow = SW_SHOWNORMAL;\r
1105         if (ShellExecuteEx(&info) == false)\r
1106         {\r
1107                 return false;\r
1108         }\r
1109 \r
1110         h = info.hProcess;\r
1111 \r
1112         *process_handle = (void *)h;\r
1113 \r
1114         return true;\r
1115 }\r
1116 bool MsExecuteExW(wchar_t *exe, wchar_t *arg, void **process_handle)\r
1117 {\r
1118         SHELLEXECUTEINFOW info;\r
1119         HANDLE h;\r
1120         // 引数チェック\r
1121         if (exe == NULL || process_handle == NULL)\r
1122         {\r
1123                 return false;\r
1124         }\r
1125 \r
1126         if (IsNt() == false)\r
1127         {\r
1128                 char exe_a[MAX_SIZE];\r
1129                 char arg_a[MAX_SIZE];\r
1130 \r
1131                 UniToStr(exe_a, sizeof(exe_a), exe);\r
1132                 UniToStr(arg_a, sizeof(arg_a), arg);\r
1133 \r
1134                 return MsExecuteEx(exe_a, arg_a, process_handle);\r
1135         }\r
1136 \r
1137         Zero(&info, sizeof(info));\r
1138         info.cbSize = sizeof(info);\r
1139         info.lpVerb = L"open";\r
1140         info.lpFile = exe;\r
1141         info.fMask = SEE_MASK_NOCLOSEPROCESS;\r
1142         info.lpParameters = arg;\r
1143         info.nShow = SW_SHOWNORMAL;\r
1144         if (ShellExecuteExW(&info) == false)\r
1145         {\r
1146                 return false;\r
1147         }\r
1148 \r
1149         h = info.hProcess;\r
1150 \r
1151         *process_handle = (void *)h;\r
1152 \r
1153         return true;\r
1154 }\r
1155 \r
1156 // ファイルの実行\r
1157 bool MsExecute(char *exe, char *arg)\r
1158 {\r
1159         DWORD d;\r
1160         // 引数チェック\r
1161         if (exe == NULL)\r
1162         {\r
1163                 return false;\r
1164         }\r
1165 \r
1166         d = (DWORD)ShellExecuteA(NULL, "open", exe, arg, MsGetExeDirName(), SW_SHOWNORMAL);\r
1167 \r
1168         if (d > 32)\r
1169         {\r
1170                 return true;\r
1171         }\r
1172 \r
1173         return false;\r
1174 }\r
1175 bool MsExecuteW(wchar_t *exe, wchar_t *arg)\r
1176 {\r
1177         DWORD d;\r
1178         // 引数チェック\r
1179         if (exe == NULL)\r
1180         {\r
1181                 return false;\r
1182         }\r
1183 \r
1184         if (IsNt() == false)\r
1185         {\r
1186                 char exe_a[MAX_SIZE];\r
1187                 char arg_a[MAX_SIZE];\r
1188 \r
1189                 UniToStr(exe_a, sizeof(exe_a), exe);\r
1190                 UniToStr(arg_a, sizeof(arg_a), arg);\r
1191 \r
1192                 return MsExecute(exe_a, arg_a);\r
1193         }\r
1194 \r
1195         d = (DWORD)ShellExecuteW(NULL, L"open", exe, arg, MsGetExeDirNameW(), SW_SHOWNORMAL);\r
1196 \r
1197         if (d > 32)\r
1198         {\r
1199                 return true;\r
1200         }\r
1201 \r
1202         return false;\r
1203 }\r
1204 \r
1205 // ディレクトリの再帰作成\r
1206 void MsUniMakeDirEx(wchar_t *name)\r
1207 {\r
1208         UINT wp;\r
1209         wchar_t *tmp;\r
1210         UINT i, len;\r
1211         // 引数チェック\r
1212         if (name == NULL)\r
1213         {\r
1214                 return;\r
1215         }\r
1216 \r
1217         tmp = ZeroMalloc(UniStrSize(name) * 2);\r
1218         wp = 0;\r
1219         len = UniStrLen(name);\r
1220         for (i = 0;i < len;i++)\r
1221         {\r
1222                 wchar_t c = name[i];\r
1223 \r
1224                 if (c == '\\')\r
1225                 {\r
1226                         if (UniStrCmpi(tmp, L"\\\\") != 0 && UniStrCmpi(tmp, L"\\") != 0)\r
1227                         {\r
1228                                 MsUniMakeDir(tmp);\r
1229                         }\r
1230                 }\r
1231 \r
1232                 tmp[wp++] = c;\r
1233         }\r
1234 \r
1235         Free(tmp);\r
1236 \r
1237         MsUniMakeDir(name);\r
1238 }\r
1239 void MsMakeDirEx(char *name)\r
1240 {\r
1241         wchar_t *name_w = CopyStrToUni(name);\r
1242 \r
1243         MsUniMakeDirEx(name_w);\r
1244 \r
1245         Free(name_w);\r
1246 }\r
1247 \r
1248 // ディレクトリの作成\r
1249 bool MsUniMakeDir(wchar_t *name)\r
1250 {\r
1251         // 引数チェック\r
1252         if (name == NULL)\r
1253         {\r
1254                 return false;\r
1255         }\r
1256 \r
1257         if (MsIsNt() == false)\r
1258         {\r
1259                 char *s = CopyUniToStr(name);\r
1260                 bool ret = MsMakeDir(s);\r
1261                 Free(s);\r
1262                 return ret;\r
1263         }\r
1264 \r
1265         return CreateDirectoryW(name, NULL);\r
1266 }\r
1267 bool MsMakeDir(char *name)\r
1268 {\r
1269         // 引数チェック\r
1270         if (name == NULL)\r
1271         {\r
1272                 return false;\r
1273         }\r
1274 \r
1275         return CreateDirectoryA(name, NULL);\r
1276 }\r
1277 \r
1278 // ディレクトリの削除\r
1279 bool MsUniDirectoryDelete(wchar_t *name)\r
1280 {\r
1281         // 引数チェック\r
1282         if (name == NULL)\r
1283         {\r
1284                 return false;\r
1285         }\r
1286 \r
1287         if (MsIsNt() == false)\r
1288         {\r
1289                 char *s = CopyUniToStr(name);\r
1290                 bool ret = MsDirectoryDelete(s);\r
1291                 Free(s);\r
1292                 return ret;\r
1293         }\r
1294 \r
1295         return RemoveDirectoryW(name);\r
1296 }\r
1297 bool MsDirectoryDelete(char *name)\r
1298 {\r
1299         // 引数チェック\r
1300         if (name == NULL)\r
1301         {\r
1302                 return false;\r
1303         }\r
1304 \r
1305         return RemoveDirectoryA(name);\r
1306 }\r
1307 \r
1308 // ファイルの削除\r
1309 bool MsUniFileDelete(wchar_t *name)\r
1310 {\r
1311         // 引数チェック\r
1312         if (name == NULL)\r
1313         {\r
1314                 return false;\r
1315         }\r
1316 \r
1317         if (MsIsNt() == false)\r
1318         {\r
1319                 bool ret;\r
1320                 char *s = CopyUniToStr(name);\r
1321                 ret = MsFileDelete(s);\r
1322                 Free(s);\r
1323                 return ret;\r
1324         }\r
1325 \r
1326         return DeleteFileW(name);\r
1327 }\r
1328 bool MsFileDelete(char *name)\r
1329 {\r
1330         // 引数チェック\r
1331         if (name == NULL)\r
1332         {\r
1333                 return false;\r
1334         }\r
1335 \r
1336         return DeleteFileA(name);\r
1337 }\r
1338 \r
1339 // 指定したファイル名がディレクトリかどうか取得する\r
1340 bool MsUniIsDirectory(wchar_t *name)\r
1341 {\r
1342         DWORD ret;\r
1343         // 引数チェック\r
1344         if (name == NULL)\r
1345         {\r
1346                 return false;\r
1347         }\r
1348 \r
1349         if (MsIsNt() == false)\r
1350         {\r
1351                 char *s = CopyUniToStr(name);\r
1352                 ret = MsIsDirectory(s);\r
1353                 Free(s);\r
1354 \r
1355                 return ret;\r
1356         }\r
1357 \r
1358         ret = GetFileAttributesW(name);\r
1359         if (ret == 0xffffffff)\r
1360         {\r
1361                 return false;\r
1362         }\r
1363 \r
1364         if (ret & FILE_ATTRIBUTE_DIRECTORY)\r
1365         {\r
1366                 return true;\r
1367         }\r
1368 \r
1369         return false;\r
1370 }\r
1371 bool MsIsDirectoryW(wchar_t *name)\r
1372 {\r
1373         return MsUniIsDirectory(name);\r
1374 }\r
1375 bool MsIsDirectory(char *name)\r
1376 {\r
1377         DWORD ret;\r
1378         char tmp[MAX_PATH];\r
1379         // 引数チェック\r
1380         if (name == NULL)\r
1381         {\r
1382                 return false;\r
1383         }\r
1384 \r
1385         InnerFilePath(tmp, sizeof(tmp), name);\r
1386 \r
1387         ret = GetFileAttributesA(tmp);\r
1388         if (ret == 0xffffffff)\r
1389         {\r
1390                 return false;\r
1391         }\r
1392 \r
1393         if (ret & FILE_ATTRIBUTE_DIRECTORY)\r
1394         {\r
1395                 return true;\r
1396         }\r
1397 \r
1398         return false;\r
1399 }\r
1400 \r
1401 // MSI ファイルから Cabinet を取り出す\r
1402 bool MsExtractCabFromMsi(char *msi, char *cab)\r
1403 {\r
1404         wchar_t msi_w[MAX_PATH];\r
1405         wchar_t cab_w[MAX_PATH];\r
1406 \r
1407         StrToUni(msi_w, sizeof(msi_w), msi);\r
1408         StrToUni(cab_w, sizeof(cab_w), cab);\r
1409 \r
1410         return MsExtractCabFromMsiW(msi_w, cab_w);\r
1411 }\r
1412 bool MsExtractCabFromMsiW(wchar_t *msi, wchar_t *cab)\r
1413 {\r
1414         BUF *b;\r
1415         bool ret = false;\r
1416         UINT i;\r
1417         char sign[] = {'M', 'S', 'C', 'F', 0, 0, 0, 0,};\r
1418         void *pointer = NULL;\r
1419         UINT current_pos = 0;\r
1420         UINT sign_size;\r
1421         // 引数チェック\r
1422         if (msi == NULL || cab == NULL)\r
1423         {\r
1424                 return false;\r
1425         }\r
1426 \r
1427         // MSI を読み込む\r
1428         b = ReadDumpW(msi);\r
1429         if (b == NULL)\r
1430         {\r
1431                 return false;\r
1432         }\r
1433 \r
1434         if (b->Size < 128)\r
1435         {\r
1436                 FreeBuf(b);\r
1437                 return false;\r
1438         }\r
1439 \r
1440         sign_size = sizeof(sign);\r
1441 \r
1442         // "MSCF" を検索する\r
1443         for (i = 0;i < (b->Size - sign_size);i++)\r
1444         {\r
1445                 char *p = ((UCHAR *)b->Buf) + i;\r
1446 \r
1447                 if (Cmp(p, sign, sign_size) == 0)\r
1448                 {\r
1449                         pointer = p;\r
1450                         current_pos = i;\r
1451                 }\r
1452         }\r
1453 \r
1454         if (pointer != NULL)\r
1455         {\r
1456                 UINT size = b->Size - current_pos;\r
1457                 BUF *b2 = NewBuf();\r
1458 \r
1459                 WriteBuf(b2, pointer, size);\r
1460 \r
1461                 ret = DumpBufW(b2, cab);\r
1462 \r
1463                 FreeBuf(b2);\r
1464 \r
1465         }\r
1466 \r
1467         FreeBuf(b);\r
1468 \r
1469         return ret;\r
1470 }\r
1471 \r
1472 // Cabinet ファイルからファイルを取り出す\r
1473 bool MsExtractCab(char *cab_name, char *dest_dir_name)\r
1474 {\r
1475         wchar_t cab_name_w[MAX_SIZE];\r
1476         wchar_t dest_dir_name_w[MAX_SIZE];\r
1477 \r
1478         StrToUni(cab_name_w, sizeof(cab_name_w), cab_name);\r
1479         StrToUni(dest_dir_name_w, sizeof(dest_dir_name_w), dest_dir_name);\r
1480 \r
1481         return MsExtractCabW(cab_name_w, dest_dir_name_w);\r
1482 }\r
1483 bool MsExtractCabW(wchar_t *cab_name, wchar_t *dest_dir_name)\r
1484 {\r
1485         wchar_t cabarc[MAX_PATH];\r
1486         wchar_t arg[MAX_PATH * 2];\r
1487         wchar_t tmp[MAX_PATH];\r
1488 \r
1489         // 引数チェック\r
1490         if (cab_name == NULL || dest_dir_name == NULL)\r
1491         {\r
1492                 return false;\r
1493         }\r
1494 \r
1495         if (MsGetCabarcExeFilenameW(cabarc, sizeof(cabarc)) == false)\r
1496         {\r
1497                 return false;\r
1498         }\r
1499 \r
1500         UniStrCpy(tmp, sizeof(tmp), dest_dir_name);\r
1501         if (UniEndWith(tmp, L"\\"))\r
1502         {\r
1503                 tmp[UniStrLen(tmp) - 1] = 0;\r
1504         }\r
1505 \r
1506         UniFormat(arg, sizeof(arg),\r
1507                 L"-o X \"%s\" * \"%s\"\\",\r
1508                 cab_name,\r
1509                 tmp);\r
1510 \r
1511         MakeDirW(dest_dir_name);\r
1512 \r
1513         if (RunW(cabarc, arg, true, true) == false)\r
1514         {\r
1515                 return false;\r
1516         }\r
1517 \r
1518         return true;\r
1519 }\r
1520 \r
1521 // cabarc.exe の展開\r
1522 bool MsGetCabarcExeFilename(char *name, UINT size)\r
1523 {\r
1524         // 引数チェック\r
1525         if (name == NULL)\r
1526         {\r
1527                 return false;\r
1528         }\r
1529 \r
1530         ConbinePath(name, size, MsGetMyTempDir(), "cabarc.exe");\r
1531 \r
1532         if (IsFileExists(name))\r
1533         {\r
1534                 return true;\r
1535         }\r
1536 \r
1537         if (FileCopy("|cabarc.exe", name) == false)\r
1538         {\r
1539                 return false;\r
1540         }\r
1541 \r
1542         return true;\r
1543 }\r
1544 bool MsGetCabarcExeFilenameW(wchar_t *name, UINT size)\r
1545 {\r
1546         // 引数チェック\r
1547         if (name == NULL)\r
1548         {\r
1549                 return false;\r
1550         }\r
1551 \r
1552         ConbinePathW(name, size, MsGetMyTempDirW(), L"cabarc.exe");\r
1553 \r
1554         if (IsFileExistsW(name))\r
1555         {\r
1556                 return true;\r
1557         }\r
1558 \r
1559         if (FileCopyW(L"|cabarc.exe", name) == false)\r
1560         {\r
1561                 return false;\r
1562         }\r
1563 \r
1564         return true;\r
1565 }\r
1566 \r
1567 // EXE ファイルから Cabinet ファイルを取り出す\r
1568 bool MsExtractCabinetFileFromExe(char *exe, char *cab)\r
1569 {\r
1570         BUF *b;\r
1571         // 引数チェック\r
1572         if (exe == NULL || cab == NULL)\r
1573         {\r
1574                 return false;\r
1575         }\r
1576 \r
1577         b = MsExtractResourceFromExe(exe, RT_RCDATA, "CABINET");\r
1578         if (b == NULL)\r
1579         {\r
1580                 return false;\r
1581         }\r
1582 \r
1583         if (DumpBuf(b, cab) == false)\r
1584         {\r
1585                 FreeBuf(b);\r
1586 \r
1587                 return false;\r
1588         }\r
1589 \r
1590         FreeBuf(b);\r
1591 \r
1592         return true;\r
1593 }\r
1594 bool MsExtractCabinetFileFromExeW(wchar_t *exe, wchar_t *cab)\r
1595 {\r
1596         BUF *b;\r
1597         // 引数チェック\r
1598         if (exe == NULL || cab == NULL)\r
1599         {\r
1600                 return false;\r
1601         }\r
1602 \r
1603         b = MsExtractResourceFromExeW(exe, RT_RCDATA, "CABINET");\r
1604         if (b == NULL)\r
1605         {\r
1606                 return false;\r
1607         }\r
1608 \r
1609         if (DumpBufW(b, cab) == false)\r
1610         {\r
1611                 FreeBuf(b);\r
1612 \r
1613                 return false;\r
1614         }\r
1615 \r
1616         FreeBuf(b);\r
1617 \r
1618         return true;\r
1619 }\r
1620 \r
1621 // EXE ファイルからリソースを取り出す\r
1622 BUF *MsExtractResourceFromExe(char *exe, char *type, char *name)\r
1623 {\r
1624         HINSTANCE h;\r
1625         HRSRC hr;\r
1626         HGLOBAL hg;\r
1627         UINT size;\r
1628         void *data;\r
1629         BUF *buf;\r
1630         // 引数チェック\r
1631         if (exe == NULL || type == NULL || name == NULL)\r
1632         {\r
1633                 return NULL;\r
1634         }\r
1635 \r
1636         h = LoadLibraryExA(exe, NULL, LOAD_LIBRARY_AS_DATAFILE);\r
1637         if (h == NULL)\r
1638         {\r
1639                 return NULL;\r
1640         }\r
1641 \r
1642         hr = FindResourceA(h, name, type);\r
1643         if (hr == NULL)\r
1644         {\r
1645                 FreeLibrary(h);\r
1646                 return NULL;\r
1647         }\r
1648 \r
1649         hg = LoadResource(h, hr);\r
1650         if (hg == NULL)\r
1651         {\r
1652                 FreeLibrary(h);\r
1653                 return NULL;\r
1654         }\r
1655 \r
1656         size = SizeofResource(h, hr);\r
1657         data = (void *)LockResource(hg);\r
1658 \r
1659         buf = NewBuf();\r
1660         WriteBuf(buf, data, size);\r
1661 \r
1662         FreeResource(hg);\r
1663         FreeLibrary(h);\r
1664 \r
1665         SeekBuf(buf, 0, 0);\r
1666 \r
1667         return buf;\r
1668 }\r
1669 BUF *MsExtractResourceFromExeW(wchar_t *exe, char *type, char *name)\r
1670 {\r
1671         HINSTANCE h;\r
1672         HRSRC hr;\r
1673         HGLOBAL hg;\r
1674         UINT size;\r
1675         void *data;\r
1676         BUF *buf;\r
1677         // 引数チェック\r
1678         if (exe == NULL || type == NULL || name == NULL)\r
1679         {\r
1680                 return NULL;\r
1681         }\r
1682 \r
1683         if (IsNt() == false)\r
1684         {\r
1685                 char exe_a[MAX_PATH];\r
1686 \r
1687                 UniToStr(exe_a, sizeof(exe_a), exe);\r
1688 \r
1689                 return MsExtractResourceFromExe(exe_a, type, name);\r
1690         }\r
1691 \r
1692         h = LoadLibraryExW(exe, NULL, LOAD_LIBRARY_AS_DATAFILE);\r
1693         if (h == NULL)\r
1694         {\r
1695                 return NULL;\r
1696         }\r
1697 \r
1698         hr = FindResource(h, name, type);\r
1699         if (hr == NULL)\r
1700         {\r
1701                 FreeLibrary(h);\r
1702                 return NULL;\r
1703         }\r
1704 \r
1705         hg = LoadResource(h, hr);\r
1706         if (hg == NULL)\r
1707         {\r
1708                 FreeLibrary(h);\r
1709                 return NULL;\r
1710         }\r
1711 \r
1712         size = SizeofResource(h, hr);\r
1713         data = (void *)LockResource(hg);\r
1714 \r
1715         buf = NewBuf();\r
1716         WriteBuf(buf, data, size);\r
1717 \r
1718         FreeResource(hg);\r
1719         FreeLibrary(h);\r
1720 \r
1721         SeekBuf(buf, 0, 0);\r
1722 \r
1723         return buf;\r
1724 }\r
1725 \r
1726 // ファイルのバージョン情報を取得する\r
1727 bool MsGetFileVersion(char *name, UINT *v1, UINT *v2, UINT *v3, UINT *v4)\r
1728 {\r
1729         void *data;\r
1730         UINT size;\r
1731         DWORD h;\r
1732         bool ret = false;\r
1733         // 引数チェック\r
1734         if (name == NULL)\r
1735         {\r
1736                 return false;\r
1737         }\r
1738 \r
1739         h = 0;\r
1740         size = GetFileVersionInfoSize(name, &h);\r
1741         if (size == 0)\r
1742         {\r
1743                 return false;\r
1744         }\r
1745 \r
1746         data = ZeroMalloc(size);\r
1747 \r
1748         if (GetFileVersionInfoA(name, 0, size, data))\r
1749         {\r
1750                 VS_FIXEDFILEINFO *info = NULL;\r
1751                 UINT info_size = 0;\r
1752                 if (VerQueryValueA(data, "\\", &info, &info_size))\r
1753                 {\r
1754                         if (v1 != NULL)\r
1755                         {\r
1756                                 *v1 = HIWORD(info->dwFileVersionMS);\r
1757                         }\r
1758 \r
1759                         if (v2 != NULL)\r
1760                         {\r
1761                                 *v2 = LOWORD(info->dwFileVersionMS);\r
1762                         }\r
1763 \r
1764                         if (v3 != NULL)\r
1765                         {\r
1766                                 *v3 = HIWORD(info->dwFileVersionLS);\r
1767                         }\r
1768 \r
1769                         if (v4 != NULL)\r
1770                         {\r
1771                                 *v4 = LOWORD(info->dwFileVersionLS);\r
1772                         }\r
1773 \r
1774                         ret = true;\r
1775                 }\r
1776         }\r
1777 \r
1778         Free(data);\r
1779 \r
1780         return ret;\r
1781 }\r
1782 bool MsGetFileVersionW(wchar_t *name, UINT *v1, UINT *v2, UINT *v3, UINT *v4)\r
1783 {\r
1784         void *data;\r
1785         UINT size;\r
1786         DWORD h;\r
1787         bool ret = false;\r
1788         // 引数チェック\r
1789         if (name == NULL)\r
1790         {\r
1791                 return false;\r
1792         }\r
1793 \r
1794         if (IsNt() == false)\r
1795         {\r
1796                 char name_a[MAX_PATH];\r
1797 \r
1798                 UniToStr(name_a, sizeof(name_a), name);\r
1799 \r
1800                 return MsGetFileVersion(name_a, v1, v2, v3, v4);\r
1801         }\r
1802 \r
1803         h = 0;\r
1804         size = GetFileVersionInfoSizeW(name, &h);\r
1805         if (size == 0)\r
1806         {\r
1807                 return false;\r
1808         }\r
1809 \r
1810         data = ZeroMalloc(size);\r
1811 \r
1812         if (GetFileVersionInfoW(name, 0, size, data))\r
1813         {\r
1814                 VS_FIXEDFILEINFO *info = NULL;\r
1815                 UINT info_size = 0;\r
1816                 if (VerQueryValue(data, "\\", &info, &info_size))\r
1817                 {\r
1818                         if (v1 != NULL)\r
1819                         {\r
1820                                 *v1 = HIWORD(info->dwFileVersionMS);\r
1821                         }\r
1822 \r
1823                         if (v2 != NULL)\r
1824                         {\r
1825                                 *v2 = LOWORD(info->dwFileVersionMS);\r
1826                         }\r
1827 \r
1828                         if (v3 != NULL)\r
1829                         {\r
1830                                 *v3 = HIWORD(info->dwFileVersionLS);\r
1831                         }\r
1832 \r
1833                         if (v4 != NULL)\r
1834                         {\r
1835                                 *v4 = LOWORD(info->dwFileVersionLS);\r
1836                         }\r
1837 \r
1838                         ret = true;\r
1839                 }\r
1840         }\r
1841 \r
1842         Free(data);\r
1843 \r
1844         return ret;\r
1845 }\r
1846 \r
1847 // ファイルを隠しファイルにする\r
1848 void MsSetFileToHidden(char *name)\r
1849 {\r
1850         char tmp[MAX_PATH];\r
1851         DWORD d;\r
1852         // 引数チェック\r
1853         if (name == NULL)\r
1854         {\r
1855                 return;\r
1856         }\r
1857 \r
1858         NormalizePath(tmp, sizeof(tmp), name);\r
1859 \r
1860         d = GetFileAttributesA(tmp);\r
1861         if (d != INVALID_FILE_ATTRIBUTES)\r
1862         {\r
1863                 d |= FILE_ATTRIBUTE_HIDDEN;\r
1864 \r
1865                 SetFileAttributesA(tmp, d);\r
1866         }\r
1867 }\r
1868 void MsSetFileToHiddenW(wchar_t *name)\r
1869 {\r
1870         wchar_t tmp[MAX_PATH];\r
1871         DWORD d;\r
1872         // 引数チェック\r
1873         if (name == NULL)\r
1874         {\r
1875                 return;\r
1876         }\r
1877 \r
1878         if (IsNt() == false)\r
1879         {\r
1880                 char name_a[MAX_SIZE];\r
1881 \r
1882                 UniToStr(name_a, sizeof(name_a), name);\r
1883 \r
1884                 MsSetFileToHidden(name_a);\r
1885 \r
1886                 return;\r
1887         }\r
1888 \r
1889         NormalizePathW(tmp, sizeof(tmp), name);\r
1890 \r
1891         d = GetFileAttributesW(tmp);\r
1892         if (d != INVALID_FILE_ATTRIBUTES)\r
1893         {\r
1894                 d |= FILE_ATTRIBUTE_HIDDEN;\r
1895 \r
1896                 SetFileAttributesW(tmp, d);\r
1897         }\r
1898 }\r
1899 \r
1900 // スリープ防止用スレッド\r
1901 void MsNoSleepThread(THREAD *thread, void *param)\r
1902 {\r
1903         MS_NOSLEEP *e;\r
1904         EXECUTION_STATE (WINAPI *_SetThreadExecutionState)(EXECUTION_STATE);\r
1905         HINSTANCE hKernel32;\r
1906         // 引数チェック\r
1907         if (thread == NULL || param == NULL)\r
1908         {\r
1909                 return;\r
1910         }\r
1911 \r
1912         hKernel32 = LoadLibrary("kernel32.dll");\r
1913 \r
1914         _SetThreadExecutionState =\r
1915                 (EXECUTION_STATE (__stdcall *)(EXECUTION_STATE))\r
1916                 GetProcAddress(hKernel32, "SetThreadExecutionState");\r
1917 \r
1918         e = (MS_NOSLEEP *)param;\r
1919 \r
1920         while (e->Halt == false)\r
1921         {\r
1922                 DWORD flag = ES_SYSTEM_REQUIRED;\r
1923 \r
1924                 if (e->NoScreenSaver)\r
1925                 {\r
1926                         flag |= ES_DISPLAY_REQUIRED;\r
1927                 }\r
1928 \r
1929                 if (_SetThreadExecutionState != NULL)\r
1930                 {\r
1931                         _SetThreadExecutionState(flag);\r
1932                 }\r
1933 \r
1934                 Wait(e->HaltEvent, 30 * 1000);\r
1935         }\r
1936 \r
1937         FreeLibrary(hKernel32);\r
1938 }\r
1939 \r
1940 // スリープ防止用スレッド (Windows Vista 用)\r
1941 void MsNoSleepThreadVista(THREAD *thread, void *param)\r
1942 {\r
1943         MS_NOSLEEP *e;\r
1944         char *key = "Control Panel\\Desktop";\r
1945         UINT64 last_set_flag = 0;\r
1946         UINT last_c_x = INFINITE, last_c_y = INFINITE;\r
1947         UINT64 last_mouse_move_time = 0;\r
1948         EXECUTION_STATE (WINAPI *_SetThreadExecutionState)(EXECUTION_STATE);\r
1949         HINSTANCE hKernel32;\r
1950         // 引数チェック\r
1951         if (thread == NULL || param == NULL)\r
1952         {\r
1953                 return;\r
1954         }\r
1955 \r
1956         hKernel32 = LoadLibrary("kernel32.dll");\r
1957 \r
1958         _SetThreadExecutionState =\r
1959                 (EXECUTION_STATE (__stdcall *)(EXECUTION_STATE))\r
1960                 GetProcAddress(hKernel32, "SetThreadExecutionState");\r
1961 \r
1962         e = (MS_NOSLEEP *)param;\r
1963 \r
1964         while (e->Halt == false)\r
1965         {\r
1966                 DWORD flag = ES_SYSTEM_REQUIRED;\r
1967                 UINT64 now = Tick64();\r
1968                 POINT p;\r
1969                 bool mouse_move = false;\r
1970 \r
1971                 Zero(&p, sizeof(p));\r
1972                 GetCursorPos(&p);\r
1973 \r
1974                 if (p.x != last_c_x || p.y != last_c_y)\r
1975                 {\r
1976                         if (last_c_x != INFINITE && last_c_y != INFINITE)\r
1977                         {\r
1978                                 mouse_move = true;\r
1979                         }\r
1980 \r
1981                         last_c_x = p.x;\r
1982                         last_c_y = p.y;\r
1983                 }\r
1984 \r
1985                 if (mouse_move)\r
1986                 {\r
1987                         last_mouse_move_time = now;\r
1988                 }\r
1989 \r
1990                 if (last_mouse_move_time == 0 || (now > (last_mouse_move_time + 50000ULL)))\r
1991                 {\r
1992                         wchar_t *active;\r
1993                         wchar_t *exe;\r
1994                         // マウスが 50 秒以上動かない場合はスクリーンセーバーの設定を削除する\r
1995 \r
1996                         active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive");\r
1997                         exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE");\r
1998 \r
1999                         if (UniToInt(active) != 0 && UniIsEmptyStr(exe) == false)\r
2000                         {\r
2001                                 // スクリーンセーバーが設定されている\r
2002                                 UniStrCpy(e->ScreenSaveActive, sizeof(e->ScreenSaveActive), active);\r
2003                                 UniStrCpy(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE), exe);\r
2004 \r
2005                                 MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", L"0");\r
2006                                 MsRegDeleteValue(REG_CURRENT_USER, key, "SCRNSAVE.EXE");\r
2007 \r
2008                                 Debug("Push SS Settings.\n");\r
2009                         }\r
2010 \r
2011                         Free(active);\r
2012                         Free(exe);\r
2013 \r
2014                         last_mouse_move_time = now;\r
2015                 }\r
2016                 else\r
2017                 {\r
2018                         if (mouse_move)\r
2019                         {\r
2020                                 if (UniIsEmptyStr(e->ScreenSaveActive) == false && UniIsEmptyStr(e->SCRNSAVE_EXE) == false)\r
2021                                 {\r
2022                                         // マウスが動いた場合でスクリーンセーバーが設定されていない場合は\r
2023                                         // スクリーンセーバーの設定を復元する\r
2024                                         wchar_t *active;\r
2025                                         wchar_t *exe;\r
2026 \r
2027                                         active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive");\r
2028                                         exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE");\r
2029 \r
2030                                         if (UniToInt(active) != 0 && UniIsEmptyStr(exe) == false)\r
2031                                         {\r
2032                                         }\r
2033                                         else\r
2034                                         {\r
2035                                                 MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", e->ScreenSaveActive);\r
2036                                                 MsRegWriteStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE", e->SCRNSAVE_EXE);\r
2037 \r
2038                                                 Zero(e->ScreenSaveActive, sizeof(e->ScreenSaveActive));\r
2039                                                 Zero(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE));\r
2040 \r
2041                                                 Debug("Pop SS Settings.\n");\r
2042                                         }\r
2043 \r
2044                                         Free(active);\r
2045                                         Free(exe);\r
2046                                 }\r
2047                         }\r
2048                 }\r
2049 \r
2050                 if (last_set_flag == 0 || (now > (last_set_flag + 50000ULL)))\r
2051                 {\r
2052                         // フラグセット (50 秒間隔)\r
2053                         last_set_flag = now;\r
2054 \r
2055                         if (_SetThreadExecutionState != NULL)\r
2056                         {\r
2057                                 _SetThreadExecutionState(flag);\r
2058                         }\r
2059                 }\r
2060 \r
2061                 Wait(e->HaltEvent, 512);\r
2062         }\r
2063 \r
2064         if (true)\r
2065         {\r
2066                 // スクリーンセーバーの設定を復元する\r
2067                 wchar_t *active;\r
2068                 wchar_t *exe;\r
2069 \r
2070                 if (UniIsEmptyStr(e->ScreenSaveActive) == false && UniIsEmptyStr(e->SCRNSAVE_EXE) == false)\r
2071                 {\r
2072                         active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive");\r
2073                         exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE");\r
2074 \r
2075                         if (UniToInt(active) != 0 && UniIsEmptyStr(exe) != 0)\r
2076                         {\r
2077                         }\r
2078                         else\r
2079                         {\r
2080                                 MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", e->ScreenSaveActive);\r
2081                                 MsRegWriteStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE", e->SCRNSAVE_EXE);\r
2082 \r
2083                                 Zero(e->ScreenSaveActive, sizeof(e->ScreenSaveActive));\r
2084                                 Zero(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE));\r
2085 \r
2086                                 Debug("Pop SS Settings.\n");\r
2087                         }\r
2088 \r
2089                         Free(active);\r
2090                         Free(exe);\r
2091                 }\r
2092         }\r
2093 \r
2094         FreeLibrary(hKernel32);\r
2095 }\r
2096 \r
2097 // スリープ防止の開始\r
2098 void *MsNoSleepStart(bool no_screensaver)\r
2099 {\r
2100         MS_NOSLEEP *e;\r
2101         bool is_vista = MsIsVista();\r
2102         bool is_nt_4 = false;\r
2103         UINT os_type = GetOsInfo()->OsType;\r
2104 \r
2105         if (OS_IS_WINDOWS_NT(os_type))\r
2106         {\r
2107                 if (GET_KETA(os_type, 100) == 1)\r
2108                 {\r
2109                         is_nt_4 = true;\r
2110                 }\r
2111         }\r
2112 \r
2113         e = ZeroMalloc(sizeof(MS_NOSLEEP));\r
2114 \r
2115         e->HaltEvent = NewEvent();\r
2116         e->NoScreenSaver = no_screensaver;\r
2117 \r
2118         if (e->NoScreenSaver == false || (is_vista == false && is_nt_4 == false))\r
2119         {\r
2120                 e->Thread = NewThread(MsNoSleepThread, e);\r
2121         }\r
2122         else\r
2123         {\r
2124                 e->Thread = NewThread(MsNoSleepThreadVista, e);\r
2125         }\r
2126 \r
2127         return (void *)e;\r
2128 }\r
2129 \r
2130 // スリープ防止の停止\r
2131 void MsNoSleepEnd(void *p)\r
2132 {\r
2133         MS_NOSLEEP *e;\r
2134         // 引数チェック\r
2135         if (p == NULL)\r
2136         {\r
2137                 return;\r
2138         }\r
2139 \r
2140         e = (MS_NOSLEEP *)p;\r
2141 \r
2142         e->Halt = true;\r
2143         Set(e->HaltEvent);\r
2144 \r
2145         WaitThread(e->Thread, INFINITE);\r
2146         ReleaseThread(e->Thread);\r
2147         ReleaseEvent(e->HaltEvent);\r
2148 \r
2149         Free(e);\r
2150 }\r
2151 \r
2152 // コンピュータ名の取得\r
2153 void MsGetComputerName(char *name, UINT size)\r
2154 {\r
2155         DWORD sz;\r
2156         // 引数チェック\r
2157         if (name == NULL)\r
2158         {\r
2159                 return;\r
2160         }\r
2161 \r
2162         sz = size;\r
2163         GetComputerName(name, &sz);\r
2164 }\r
2165 \r
2166 // マウスカーソルの位置のハッシュ値を取得\r
2167 UINT MsGetCursorPosHash()\r
2168 {\r
2169         POINT p;\r
2170 \r
2171         Zero(&p, sizeof(p));\r
2172 \r
2173         if (GetCursorPos(&p) == false)\r
2174         {\r
2175                 return 0;\r
2176         }\r
2177 \r
2178         return MAKELONG((USHORT)p.x, (USHORT)p.y);\r
2179 }\r
2180 \r
2181 // 一般ユーザー権限としてのプロセスの起動\r
2182 void *MsRunAsUserEx(char *filename, char *arg, bool hide)\r
2183 {\r
2184         void *ret = MsRunAsUserExInner(filename, arg, hide);\r
2185 \r
2186         if (ret == NULL)\r
2187         {\r
2188                 Debug("MsRunAsUserExInner Failed.\n");\r
2189                 ret = Win32RunEx(filename, arg, hide);\r
2190         }\r
2191 \r
2192         return ret;\r
2193 }\r
2194 void *MsRunAsUserExW(wchar_t *filename, wchar_t *arg, bool hide)\r
2195 {\r
2196         void *ret = MsRunAsUserExInnerW(filename, arg, hide);\r
2197 \r
2198         if (ret == NULL)\r
2199         {\r
2200                 Debug("MsRunAsUserExInner Failed.\n");\r
2201                 ret = Win32RunExW(filename, arg, hide);\r
2202         }\r
2203 \r
2204         return ret;\r
2205 }\r
2206 void *MsRunAsUserExInner(char *filename, char *arg, bool hide)\r
2207 {\r
2208         void *ret;\r
2209         wchar_t *filename_w;\r
2210         wchar_t *arg_w;\r
2211 \r
2212         filename_w = CopyStrToUni(filename);\r
2213         arg_w = CopyStrToUni(arg);\r
2214 \r
2215         ret = MsRunAsUserExInnerW(filename_w, arg_w, hide);\r
2216 \r
2217         Free(filename_w);\r
2218         Free(arg_w);\r
2219 \r
2220         return ret;\r
2221 }\r
2222 void *MsRunAsUserExInnerW(wchar_t *filename, wchar_t *arg, bool hide)\r
2223 {\r
2224         STARTUPINFOW info;\r
2225         PROCESS_INFORMATION ret;\r
2226         wchar_t cmdline[MAX_SIZE];\r
2227         wchar_t name[MAX_PATH];\r
2228         HANDLE hToken;\r
2229         // 引数チェック\r
2230         if (filename == NULL)\r
2231         {\r
2232                 return NULL;\r
2233         }\r
2234 \r
2235         if (MsIsVista() == false)\r
2236         {\r
2237                 // Windows Vista 以外では使用できない\r
2238                 return NULL;\r
2239         }\r
2240 \r
2241         UniStrCpy(name, sizeof(name), filename);\r
2242         UniTrim(name);\r
2243 \r
2244         if (UniSearchStr(name, L"\"", 0) == INFINITE)\r
2245         {\r
2246                 if (arg == NULL)\r
2247                 {\r
2248                         UniFormat(cmdline, sizeof(cmdline), L"%s", name);\r
2249                 }\r
2250                 else\r
2251                 {\r
2252                         UniFormat(cmdline, sizeof(cmdline), L"%s %s", name, arg);\r
2253                 }\r
2254         }\r
2255         else\r
2256         {\r
2257                 if (arg == NULL)\r
2258                 {\r
2259                         UniFormat(cmdline, sizeof(cmdline), L"\"%s\"", name);\r
2260                 }\r
2261                 else\r
2262                 {\r
2263                         UniFormat(cmdline, sizeof(cmdline), L"\"%s\" %s", name, arg);\r
2264                 }\r
2265         }\r
2266 \r
2267         Zero(&info, sizeof(info));\r
2268         Zero(&ret, sizeof(ret));\r
2269         info.cb = sizeof(info);\r
2270         info.dwFlags = STARTF_USESHOWWINDOW;\r
2271         info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);\r
2272 \r
2273         UniTrim(cmdline);\r
2274 \r
2275         hToken = MsCreateUserToken();\r
2276 \r
2277         if (hToken == NULL)\r
2278         {\r
2279                 return NULL;\r
2280         }\r
2281 \r
2282         if (ms->nt->CreateProcessAsUserW(hToken, NULL, cmdline, NULL, NULL, FALSE,\r
2283                 (hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,\r
2284                 NULL, NULL, &info, &ret) == FALSE)\r
2285         {\r
2286                 return NULL;\r
2287         }\r
2288 \r
2289         CloseHandle(hToken);\r
2290 \r
2291         CloseHandle(ret.hThread);\r
2292         return ret.hProcess;\r
2293 }\r
2294 \r
2295 // アカウント名から SID を取得する\r
2296 SID *MsGetSidFromAccountName(char *name)\r
2297 {\r
2298         SID *sid;\r
2299         UINT sid_size = 4096;\r
2300         char *domain_name;\r
2301         UINT domain_name_size = 4096;\r
2302         SID_NAME_USE use = SidTypeUser;\r
2303         // 引数チェック\r
2304         if (name == NULL)\r
2305         {\r
2306                 return NULL;\r
2307         }\r
2308 \r
2309         if (MsIsNt() == false)\r
2310         {\r
2311                 return NULL;\r
2312         }\r
2313 \r
2314         sid = ZeroMalloc(sid_size);\r
2315         domain_name = ZeroMalloc(domain_name_size);\r
2316 \r
2317         if (ms->nt->LookupAccountNameA(NULL, name, sid, &sid_size, domain_name, &domain_name_size, &use) == false)\r
2318         {\r
2319                 Free(sid);\r
2320                 Free(domain_name);\r
2321                 return NULL;\r
2322         }\r
2323 \r
2324         Free(domain_name);\r
2325 \r
2326         return sid;\r
2327 }\r
2328 \r
2329 // SID を解放する\r
2330 void MsFreeSid(SID *sid)\r
2331 {\r
2332         // 引数チェック\r
2333         if (sid == NULL)\r
2334         {\r
2335                 return;\r
2336         }\r
2337 \r
2338         Free(sid);\r
2339 }\r
2340 \r
2341 // 一般ユーザーのトークンを作成する\r
2342 HANDLE MsCreateUserToken()\r
2343 {\r
2344         char *medium_sid = "S-1-16-8192";\r
2345         char *administrators_sid = "S-1-5-32-544";\r
2346         SID *sid = NULL;\r
2347         TOKEN_MANDATORY_LABEL til;\r
2348         HANDLE hCurrentToken, hNewToken;\r
2349         if (MsIsNt() == false)\r
2350         {\r
2351                 return NULL;\r
2352         }\r
2353         if (ms->nt->ConvertStringSidToSidA == NULL ||\r
2354                 ms->nt->OpenProcessToken == NULL ||\r
2355                 ms->nt->DuplicateTokenEx == NULL ||\r
2356                 ms->nt->GetTokenInformation == NULL ||\r
2357                 ms->nt->SetTokenInformation == NULL)\r
2358         {\r
2359                 return NULL;\r
2360         }\r
2361 \r
2362         Zero(&til, sizeof(til));\r
2363 \r
2364         if (ms->nt->ConvertStringSidToSidA(medium_sid, &sid) == false)\r
2365         {\r
2366                 return NULL;\r
2367         }\r
2368 \r
2369         til.Label.Attributes = SE_GROUP_INTEGRITY;\r
2370         til.Label.Sid = sid;\r
2371 \r
2372         if (ms->nt->OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hCurrentToken) == false)\r
2373         {\r
2374                 LocalFree(sid);\r
2375                 return NULL;\r
2376         }\r
2377 \r
2378         if (ms->nt->DuplicateTokenEx(hCurrentToken, MAXIMUM_ALLOWED, NULL,\r
2379                 SecurityImpersonation, TokenPrimary, &hNewToken) == false)\r
2380         {\r
2381                 CloseHandle(hCurrentToken);\r
2382                 LocalFree(sid);\r
2383                 return NULL;\r
2384         }\r
2385 \r
2386         if (ms->nt->SetTokenInformation(hNewToken, VistaTokenIntegrityLevel, &til,\r
2387                 sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(sid)) == false)\r
2388         {\r
2389                 CloseHandle(hNewToken);\r
2390                 CloseHandle(hCurrentToken);\r
2391                 LocalFree(sid);\r
2392                 return NULL;\r
2393         }\r
2394 \r
2395         CloseHandle(hCurrentToken);\r
2396         LocalFree(sid);\r
2397 \r
2398         return hNewToken;\r
2399 }\r
2400 \r
2401 // ファイルのデジタル署名をチェック\r
2402 bool MsCheckFileDigitalSignature(HWND hWnd, char *name, bool *danger)\r
2403 {\r
2404         wchar_t tmp[MAX_PATH];\r
2405 \r
2406         swprintf(tmp, sizeof(tmp), L"%S", name);\r
2407 \r
2408         return MsCheckFileDigitalSignatureW(hWnd, tmp, danger);\r
2409 }\r
2410 bool MsCheckFileDigitalSignatureW(HWND hWnd, wchar_t *name, bool *danger)\r
2411 {\r
2412         HRESULT ret = S_OK;\r
2413         wchar_t *tmp;\r
2414         LONG (WINAPI *_WinVerifyTrust)(HWND, GUID *, LPVOID) = NULL;\r
2415         HINSTANCE hDll;\r
2416         // 引数チェック\r
2417         if (name == NULL)\r
2418         {\r
2419                 return false;\r
2420         }\r
2421 \r
2422         if (danger != NULL)\r
2423         {\r
2424                 *danger = false;\r
2425         }\r
2426 \r
2427         tmp = name;\r
2428 \r
2429         hDll = LoadLibrary("Wintrust.dll");\r
2430         if (hDll == NULL)\r
2431         {\r
2432                 return false;\r
2433         }\r
2434 \r
2435         _WinVerifyTrust =\r
2436                 (LONG (__stdcall *)(HWND,GUID *,LPVOID))\r
2437                 GetProcAddress(hDll, "WinVerifyTrust");\r
2438         if (_WinVerifyTrust == NULL)\r
2439         {\r
2440                 FreeLibrary(hDll);\r
2441                 return false;\r
2442         }\r
2443         else\r
2444         {\r
2445                 GUID action_id = WINTRUST_ACTION_GENERIC_VERIFY_V2;\r
2446                 WINTRUST_FILE_INFO file;\r
2447                 WINTRUST_DATA data;\r
2448 \r
2449                 Zero(&file, sizeof(file));\r
2450                 file.cbStruct = sizeof(file);\r
2451                 file.pcwszFilePath = tmp;\r
2452 \r
2453                 Zero(&data, sizeof(data));\r
2454                 data.cbStruct = sizeof(data);\r
2455                 data.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;\r
2456                 data.dwUIChoice = (hWnd != NULL ? WTD_UI_NOGOOD : WTD_UI_NONE);\r
2457                 data.dwProvFlags = WTD_REVOCATION_CHECK_CHAIN;\r
2458                 data.dwUnionChoice = WTD_CHOICE_FILE;\r
2459                 data.pFile = &file;\r
2460 \r
2461                 ret = _WinVerifyTrust(hWnd, &action_id, &data);\r
2462 \r
2463                 if (ret == ERROR_SUCCESS && danger != NULL)\r
2464                 {\r
2465                         if (hWnd != NULL)\r
2466                         {\r
2467                                 if (MsCheckFileDigitalSignatureW(NULL, name, NULL) == false)\r
2468                                 {\r
2469                                         // 危険なファイルだがユーザーが [OK] を選択してしまった\r
2470                                         *danger = true;\r
2471                                 }\r
2472                         }\r
2473                 }\r
2474         }\r
2475 \r
2476         FreeLibrary(hDll);\r
2477 \r
2478         if (ret != ERROR_SUCCESS)\r
2479         {\r
2480                 return false;\r
2481         }\r
2482 \r
2483         return true;\r
2484 }\r
2485 \r
2486 // WoW64 リダイレクションを有効または無効にする\r
2487 void MsSetWow64FileSystemRedirectionEnable(bool enable)\r
2488 {\r
2489         if (MsIs64BitWindows() == false)\r
2490         {\r
2491                 return;\r
2492         }\r
2493 \r
2494         if (ms->nt->Wow64EnableWow64FsRedirection == NULL)\r
2495         {\r
2496                 return;\r
2497         }\r
2498 \r
2499         ms->nt->Wow64EnableWow64FsRedirection(enable ? 1 : 0);\r
2500 }\r
2501 \r
2502 // WoW64 リダイレクションを無効にする\r
2503 void *MsDisableWow64FileSystemRedirection()\r
2504 {\r
2505         void *p = NULL;\r
2506         if (MsIs64BitWindows() == false)\r
2507         {\r
2508                 return NULL;\r
2509         }\r
2510 \r
2511         if (ms->nt->Wow64DisableWow64FsRedirection == NULL ||\r
2512                 ms->nt->Wow64RevertWow64FsRedirection == NULL)\r
2513         {\r
2514                 return NULL;\r
2515         }\r
2516 \r
2517         if (ms->nt->Wow64DisableWow64FsRedirection(&p) == false)\r
2518         {\r
2519                 return NULL;\r
2520         }\r
2521 \r
2522         if (p == NULL)\r
2523         {\r
2524                 p = (void *)0x12345678;\r
2525         }\r
2526 \r
2527         return p;\r
2528 }\r
2529 \r
2530 // WoW64 リダイレクションを元に戻す\r
2531 void MsRestoreWow64FileSystemRedirection(void *p)\r
2532 {\r
2533         // 引数チェック\r
2534         if (p == NULL)\r
2535         {\r
2536                 return;\r
2537         }\r
2538         if (p == (void *)0x12345678)\r
2539         {\r
2540                 p = NULL;\r
2541         }\r
2542         if (MsIs64BitWindows() == false)\r
2543         {\r
2544                 return;\r
2545         }\r
2546 \r
2547         if (ms->nt->Wow64DisableWow64FsRedirection == NULL ||\r
2548                 ms->nt->Wow64RevertWow64FsRedirection == NULL)\r
2549         {\r
2550                 return;\r
2551         }\r
2552 \r
2553         ms->nt->Wow64RevertWow64FsRedirection(p);\r
2554 }\r
2555 \r
2556 // 現在 x64 版 Windows が動作しているかどうか取得\r
2557 bool MsIsX64()\r
2558 {\r
2559         SYSTEM_INFO info;\r
2560 \r
2561         if (MsIs64BitWindows() == false)\r
2562         {\r
2563                 return false;\r
2564         }\r
2565         if (ms->nt->GetNativeSystemInfo == NULL)\r
2566         {\r
2567                 return false;\r
2568         }\r
2569 \r
2570         Zero(&info, sizeof(info));\r
2571         ms->nt->GetNativeSystemInfo(&info);\r
2572 \r
2573         if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)\r
2574         {\r
2575                 return true;\r
2576         }\r
2577 \r
2578         return false;\r
2579 }\r
2580 \r
2581 // 現在 IA64 版 Windows が動作しているかどうか取得\r
2582 bool MsIsIA64()\r
2583 {\r
2584         if (MsIs64BitWindows() == false)\r
2585         {\r
2586                 return false;\r
2587         }\r
2588 \r
2589         if (MsIsX64())\r
2590         {\r
2591                 return false;\r
2592         }\r
2593 \r
2594         return true;\r
2595 }\r
2596 \r
2597 // 64bit Windows かどうか取得\r
2598 bool MsIs64BitWindows()\r
2599 {\r
2600         if (Is64())\r
2601         {\r
2602                 return true;\r
2603         }\r
2604         else\r
2605         {\r
2606                 if (MsIsNt() == false)\r
2607                 {\r
2608                         return false;\r
2609                 }\r
2610                 else\r
2611                 {\r
2612                         if (ms == NULL || ms->nt == NULL)\r
2613                         {\r
2614                                 return false;\r
2615                         }\r
2616 \r
2617                         if (ms->nt->IsWow64Process == NULL)\r
2618                         {\r
2619                                 return false;\r
2620                         }\r
2621                         else\r
2622                         {\r
2623                                 bool b = false;\r
2624                                 if (ms->nt->IsWow64Process(GetCurrentProcess(), &b) == false)\r
2625                                 {\r
2626                                         return false;\r
2627                                 }\r
2628                                 return b;\r
2629                         }\r
2630                 }\r
2631         }\r
2632 }\r
2633 \r
2634 // Windows ファイアウォール登録\r
2635 void MsRegistWindowsFirewallEx2(char *title, char *exe)\r
2636 {\r
2637         char *dir = MsGetExeDirName();\r
2638         char tmp[MAX_PATH];\r
2639         // 引数チェック\r
2640         if (title == NULL || exe == NULL)\r
2641         {\r
2642                 return;\r
2643         }\r
2644 \r
2645         ConbinePath(tmp, sizeof(tmp), dir, exe);\r
2646 \r
2647         if (IsFileExists(tmp) == false)\r
2648         {\r
2649                 return;\r
2650         }\r
2651 \r
2652         MsRegistWindowsFirewallEx(title, tmp);\r
2653 }\r
2654 void MsRegistWindowsFirewall(char *title)\r
2655 {\r
2656         // 引数チェック\r
2657         if (title == NULL)\r
2658         {\r
2659                 return;\r
2660         }\r
2661 \r
2662         MsRegistWindowsFirewallEx(title, MsGetExeFileName());\r
2663 }\r
2664 void MsRegistWindowsFirewallEx(char *title, char *exe)\r
2665 {\r
2666         char *data =\r
2667                 "Option Explicit\r\nConst NET_FW_PROFILE_DOMAIN = 0\r\nConst NET_FW_PROFILE_STANDARD = 1\r\n"\r
2668                 "Const NET_FW_SCOPE_ALL = 0\r\nConst NET_FW_IP_VERSION_ANY = 2\r\nDim fwMgr\r\n"\r
2669                 "Set fwMgr = CreateObject(\"HNetCfg.FwMgr\")\r\nDim profile\r\n"\r
2670                 "Set profile = fwMgr.LocalPolicy.CurrentProfile\r\nDim app\r\n"\r
2671                 "Set app = CreateObject(\"HNetCfg.FwAuthorizedApplication\")\r\n"\r
2672                 "app.ProcessImageFileName = \"$PATH$\"\r\napp.Name = \"$TITLE$\"\r\n"\r
2673                 "app.Scope = NET_FW_SCOPE_ALL\r\napp.IpVersion = NET_FW_IP_VERSION_ANY\r\n"\r
2674                 "app.Enabled = TRUE\r\nOn Error Resume Next\r\nprofile.AuthorizedApplications."\r
2675                 "Add app\r\n";\r
2676         char *tmp;\r
2677         UINT tmp_size;\r
2678         char filename[MAX_PATH];\r
2679         char cscript[MAX_PATH];\r
2680         char arg[MAX_PATH];\r
2681         UINT ostype;\r
2682         IO *o;\r
2683         char hash[MAX_PATH];\r
2684         UCHAR hashbin[SHA1_SIZE];\r
2685         // 引数チェック\r
2686         if (title == NULL || exe == NULL)\r
2687         {\r
2688                 return;\r
2689         }\r
2690 \r
2691         // OS チェック (Windows XP, Windows Server 2003, Windows Vista, Windows 7 以外では実施しない)\r
2692         ostype = GetOsInfo()->OsType;\r
2693         if (OS_IS_WINDOWS_NT(ostype) == false)\r
2694         {\r
2695                 return;\r
2696         }\r
2697         if (GET_KETA(ostype, 100) != 3 && GET_KETA(ostype, 100) != 4 && GET_KETA(ostype, 100) != 5 && GET_KETA(ostype, 100) != 6)\r
2698         {\r
2699                 return;\r
2700         }\r
2701 \r
2702         tmp_size = StrLen(data) * 4;\r
2703         tmp = ZeroMalloc(tmp_size);\r
2704 \r
2705         HashSha1(hashbin, exe, StrLen(exe));\r
2706         BinToStr(hash, sizeof(hash), hashbin, 6);\r
2707 \r
2708         ReplaceStrEx(tmp, tmp_size, data, "$TITLE$", title, false);\r
2709         ReplaceStrEx(tmp, tmp_size, tmp, "$PATH$", exe, false);\r
2710 \r
2711         Format(filename, sizeof(filename), "%s\\winfire_%s.vbs", MsGetMyTempDir(), hash);\r
2712         o = FileCreate(filename);\r
2713         FileWrite(o, tmp, StrLen(tmp));\r
2714         FileClose(o);\r
2715 \r
2716         Format(cscript, sizeof(cscript), "%s\\cscript.exe", MsGetSystem32Dir());\r
2717         Format(arg, sizeof(arg), "\"%s\"", filename);\r
2718 \r
2719         Run(cscript, arg, true, false);\r
2720 \r
2721         Debug("cscript %s\n", arg);\r
2722 \r
2723         Free(tmp);\r
2724 }\r
2725 \r
2726 // Vista 用ドライバインストーラの実行\r
2727 bool MsExecDriverInstaller(char *arg)\r
2728 {\r
2729         wchar_t tmp[MAX_PATH];\r
2730         wchar_t hamcore_dst[MAX_PATH];\r
2731         wchar_t hamcore_src[MAX_PATH];\r
2732         HANDLE h;\r
2733         UINT retcode;\r
2734         SHELLEXECUTEINFOW info;\r
2735         wchar_t *src_exe;\r
2736         wchar_t *arg_w;\r
2737         // 引数チェック\r
2738         if (arg == NULL)\r
2739         {\r
2740                 return false;\r
2741         }\r
2742 \r
2743         UniFormat(hamcore_dst, sizeof(hamcore_dst), L"%s\\hamcore.utvpn", MsGetMyTempDirW());\r
2744         UniFormat(hamcore_src, sizeof(hamcore_src), L"%s\\hamcore.utvpn", MsGetExeDirNameW());\r
2745 \r
2746         // ファイル展開\r
2747         src_exe = VISTA_DRIVER_INSTALLER_SRC;\r
2748 \r
2749         if (MsIsX64())\r
2750         {\r
2751                 src_exe = VISTA_DRIVER_INSTALLER_SRC_X64;\r
2752         }\r
2753         if (MsIsIA64())\r
2754         {\r
2755                 src_exe = VISTA_DRIVER_INSTALLER_SRC_IA64;\r
2756         }\r
2757 \r
2758         UniFormat(tmp, sizeof(tmp), VISTA_DRIVER_INSTALLER_DST, MsGetMyTempDirW());\r
2759 \r
2760         if (FileCopyW(src_exe, tmp) == false)\r
2761         {\r
2762                 return false;\r
2763         }\r
2764 \r
2765         if (FileCopyW(hamcore_src, hamcore_dst) == false)\r
2766         {\r
2767                 return false;\r
2768         }\r
2769 \r
2770         arg_w = CopyStrToUni(arg);\r
2771 \r
2772         // 実行\r
2773         Zero(&info, sizeof(info));\r
2774         info.cbSize = sizeof(info);\r
2775         info.lpVerb = L"open";\r
2776         info.lpFile = tmp;\r
2777         info.fMask = SEE_MASK_NOCLOSEPROCESS;\r
2778         info.lpParameters = arg_w;\r
2779         info.nShow = SW_SHOWNORMAL;\r
2780         if (ShellExecuteExW(&info) == false)\r
2781         {\r
2782                 Free(arg_w);\r
2783                 return false;\r
2784         }\r
2785 \r
2786         Free(arg_w);\r
2787 \r
2788         h = info.hProcess;\r
2789         retcode = 1;\r
2790 \r
2791         while (true)\r
2792         {\r
2793                 // 完了まで待機\r
2794                 WaitForSingleObject(h, INFINITE);\r
2795 \r
2796                 // 終了コードを取得\r
2797                 retcode = 1;\r
2798                 if (GetExitCodeProcess(h, &retcode) == false)\r
2799                 {\r
2800                         break;\r
2801                 }\r
2802 \r
2803                 if (retcode != STILL_ACTIVE)\r
2804                 {\r
2805                         break;\r
2806                 }\r
2807         }\r
2808 \r
2809         CloseHandle(h);\r
2810 \r
2811         if (retcode & 1)\r
2812         {\r
2813                 return false;\r
2814         }\r
2815 \r
2816         return true;\r
2817 }\r
2818 \r
2819 // 現在のスレッドのロケールを取得\r
2820 UINT MsGetThreadLocale()\r
2821 {\r
2822         return (UINT)GetThreadLocale();\r
2823 }\r
2824 \r
2825 // 現在のコンソールの横幅を設定する\r
2826 UINT MsSetConsoleWidth(UINT size)\r
2827 {\r
2828         HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);\r
2829         CONSOLE_SCREEN_BUFFER_INFO info;\r
2830         COORD c;\r
2831         UINT old_x, old_y;\r
2832         // 引数チェック\r
2833         if (size == 0)\r
2834         {\r
2835                 return 0;\r
2836         }\r
2837         if (h == INVALID_HANDLE_VALUE)\r
2838         {\r
2839                 return 0;\r
2840         }\r
2841 \r
2842         Zero(&info, sizeof(info));\r
2843         if (GetConsoleScreenBufferInfo(h, &info) == false)\r
2844         {\r
2845                 return 0;\r
2846         }\r
2847 \r
2848         old_x = info.dwSize.X;\r
2849         old_y = info.dwSize.Y;\r
2850 \r
2851         c.X = size;\r
2852         c.Y = old_y;\r
2853 \r
2854         SetConsoleScreenBufferSize(h, c);\r
2855 \r
2856         return old_x;\r
2857 }\r
2858 \r
2859 // 現在のコンソールの横幅を取得する\r
2860 UINT MsGetConsoleWidth()\r
2861 {\r
2862         HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);\r
2863         CONSOLE_SCREEN_BUFFER_INFO info;\r
2864 \r
2865         if (h == INVALID_HANDLE_VALUE)\r
2866         {\r
2867                 return 80;\r
2868         }\r
2869 \r
2870         Zero(&info, sizeof(info));\r
2871         if (GetConsoleScreenBufferInfo(h, &info) == false)\r
2872         {\r
2873                 return 80;\r
2874         }\r
2875 \r
2876         return info.dwSize.X;\r
2877 }\r
2878 \r
2879 // MS-IME を無効にする\r
2880 bool MsDisableIme()\r
2881 {\r
2882         HINSTANCE h;\r
2883         bool ret = false;\r
2884         char dll_name[MAX_PATH];\r
2885         BOOL (WINAPI *_ImmDisableIME)(DWORD);\r
2886 \r
2887         Format(dll_name, sizeof(dll_name), "%s\\imm32.dll", MsGetSystem32Dir());\r
2888         h = MsLoadLibrary(dll_name);\r
2889         if (h == NULL)\r
2890         {\r
2891                 return false;\r
2892         }\r
2893 \r
2894         _ImmDisableIME = (BOOL (__stdcall *)(DWORD))GetProcAddress(h, "ImmDisableIME");\r
2895 \r
2896         if (_ImmDisableIME != NULL)\r
2897         {\r
2898                 ret = _ImmDisableIME(-1);\r
2899         }\r
2900 \r
2901         FreeLibrary(h);\r
2902 \r
2903         return ret;\r
2904 }\r
2905 \r
2906 // 現在時刻を表示する\r
2907 void MsPrintTick()\r
2908 {\r
2909         UINT tick = timeGetTime();\r
2910         static UINT tick_init = 0;\r
2911         if (tick_init == 0)\r
2912         {\r
2913                 tick_init = tick;\r
2914                 tick = 0;\r
2915         }\r
2916         else\r
2917         {\r
2918                 tick -= tick_init;\r
2919         }\r
2920 \r
2921         printf("[%u]\n", tick);\r
2922 }\r
2923 \r
2924 // LoadLibrary の hamcore 対応版 (データファイルとして読み込み)\r
2925 void *MsLoadLibraryAsDataFileW(wchar_t *name)\r
2926 {\r
2927         BUF *b;\r
2928         wchar_t tmp_dll_name[MAX_SIZE];\r
2929         char hash_str[MAX_SIZE];\r
2930         UCHAR hash[SHA1_SIZE];\r
2931         // 引数チェック\r
2932         if (name == NULL)\r
2933         {\r
2934                 return NULL;\r
2935         }\r
2936 \r
2937         Hash(hash, name, UniStrLen(name), true);\r
2938 \r
2939         BinToStr(hash_str, sizeof(hash_str), hash, 4);\r
2940 \r
2941         UniFormat(tmp_dll_name, sizeof(tmp_dll_name), L"%s\\%S.dll", MsGetMyTempDirW(), hash_str);\r
2942 \r
2943         if (IsFileExistsW(tmp_dll_name) == false)\r
2944         {\r
2945                 b = ReadDumpW(name);\r
2946                 if (b == NULL)\r
2947                 {\r
2948                         return NULL;\r
2949                 }\r
2950 \r
2951                 DumpBufW(b, tmp_dll_name);\r
2952                 FreeBuf(b);\r
2953         }\r
2954 \r
2955         return LoadLibraryExW(tmp_dll_name, NULL, LOAD_LIBRARY_AS_DATAFILE);\r
2956 }\r
2957 void *MsLoadLibraryAsDataFile(char *name)\r
2958 {\r
2959         wchar_t name_w[MAX_SIZE];\r
2960         // 引数チェック\r
2961         if (name == NULL)\r
2962         {\r
2963                 return NULL;\r
2964         }\r
2965 \r
2966         StrToUni(name_w, sizeof(name_w), name);\r
2967 \r
2968         return MsLoadLibraryAsDataFileW(name_w);\r
2969 }\r
2970 \r
2971 // LoadLibrary の hamcore 対応版\r
2972 void *MsLoadLibraryW(wchar_t *name)\r
2973 {\r
2974         BUF *b;\r
2975         wchar_t tmp_dll_name[MAX_SIZE];\r
2976         char hash_str[MAX_SIZE];\r
2977         UCHAR hash[SHA1_SIZE];\r
2978         // 引数チェック\r
2979         if (name == NULL)\r
2980         {\r
2981                 return NULL;\r
2982         }\r
2983 \r
2984         Hash(hash, name, UniStrSize(name), true);\r
2985 \r
2986         BinToStr(hash_str, sizeof(hash_str), hash, 4);\r
2987 \r
2988         UniFormat(tmp_dll_name, sizeof(tmp_dll_name), L"%s\\%S.dll", MsGetMyTempDirW(), hash_str);\r
2989 \r
2990         if (IsFileExistsW(tmp_dll_name) == false)\r
2991         {\r
2992                 b = ReadDumpW(name);\r
2993                 if (b == NULL)\r
2994                 {\r
2995                         return NULL;\r
2996                 }\r
2997 \r
2998                 DumpBufW(b, tmp_dll_name);\r
2999                 FreeBuf(b);\r
3000         }\r
3001 \r
3002         if (IsNt())\r
3003         {\r
3004                 return LoadLibraryW(tmp_dll_name);\r
3005         }\r
3006         else\r
3007         {\r
3008                 char tmp_dll_name_a[MAX_SIZE];\r
3009                 HINSTANCE ret;\r
3010 \r
3011                 UniToStr(tmp_dll_name_a, sizeof(tmp_dll_name_a), tmp_dll_name);\r
3012 \r
3013                 ret = LoadLibraryA(tmp_dll_name_a);\r
3014 \r
3015                 return ret;\r
3016         }\r
3017 }\r
3018 void *MsLoadLibrary(char *name)\r
3019 {\r
3020         wchar_t name_w[MAX_SIZE];\r
3021         // 引数チェック\r
3022         if (name == NULL)\r
3023         {\r
3024                 return NULL;\r
3025         }\r
3026 \r
3027         StrToUni(name_w, sizeof(name_w), name);\r
3028 \r
3029         return MsLoadLibraryW(name_w);\r
3030 }\r
3031 \r
3032 // 単一のアダプタの取得\r
3033 MS_ADAPTER *MsGetAdapter(char *title)\r
3034 {\r
3035         MS_ADAPTER_LIST *o;\r
3036         MS_ADAPTER *ret = NULL;\r
3037         UINT i;\r
3038         // 引数チェック\r
3039         if (title == NULL)\r
3040         {\r
3041                 return NULL;\r
3042         }\r
3043 \r
3044         o = MsCreateAdapterList();\r
3045         if (o == NULL)\r
3046         {\r
3047                 return NULL;\r
3048         }\r
3049 \r
3050         for (i = 0;i < o->Num;i++)\r
3051         {\r
3052                 if (StrCmpi(o->Adapters[i]->Title, title) == 0)\r
3053                 {\r
3054                         ret = MsCloneAdapter(o->Adapters[i]);\r
3055                         break;\r
3056                 }\r
3057         }\r
3058 \r
3059         MsFreeAdapterList(o);\r
3060 \r
3061         return ret;\r
3062 }\r
3063 \r
3064 // 32 ビットオーバーフローチェック\r
3065 #define CHECK_32BIT_OVERFLOW(old_value, new_value)                              \\r
3066 {                                                                                                                               \\r
3067         if ((old_value) > (new_value))                                                          \\r
3068         {                                                                                                                       \\r
3069                 (new_value) += ((UINT64)4294967296ULL);                                 \\r
3070         }                                                                                                                       \\r
3071 }\r
3072 \r
3073 // 指定したアダプタの TCP/IP 情報を取得する\r
3074 void MsGetAdapterTcpIpInformation(MS_ADAPTER *a)\r
3075 {\r
3076         IP_ADAPTER_INFO *info, *info_top;\r
3077         UINT info_size;\r
3078         UINT ret;\r
3079         // 引数チェック\r
3080         if (a == NULL)\r
3081         {\r
3082                 return;\r
3083         }\r
3084 \r
3085         if (w32net->GetAdaptersInfo == NULL)\r
3086         {\r
3087                 return;\r
3088         }\r
3089 \r
3090         info_top = ZeroMalloc(sizeof(IP_ADAPTER_INFO));\r
3091         info_size = sizeof(IP_ADAPTER_INFO);\r
3092 \r
3093         ret = w32net->GetAdaptersInfo(info_top, &info_size);\r
3094         if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW)\r
3095         {\r
3096                 Free(info_top);\r
3097                 info_size *= 2;\r
3098                 info_top = ZeroMalloc(info_size);\r
3099 \r
3100                 if (w32net->GetAdaptersInfo(info_top, &info_size) != NO_ERROR)\r
3101                 {\r
3102                         Free(info_top);\r
3103                         return;\r
3104                 }\r
3105         }\r
3106         else if (ret != NO_ERROR)\r
3107         {\r
3108                 Free(info_top);\r
3109                 return;\r
3110         }\r
3111 \r
3112         // 自分のエントリを検索する\r
3113         info = info_top;\r
3114 \r
3115         while (info != NULL)\r
3116         {\r
3117                 if (info->Index == a->Index)\r
3118                 {\r
3119                         IP_ADDR_STRING *s;\r
3120 \r
3121                         // IP アドレス\r
3122                         a->NumIpAddress = 0;\r
3123                         s = &info->IpAddressList;\r
3124                         while (s != NULL)\r
3125                         {\r
3126                                 if (a->NumIpAddress < MAX_MS_ADAPTER_IP_ADDRESS)\r
3127                                 {\r
3128                                         StrToIP(&a->IpAddresses[a->NumIpAddress], s->IpAddress.String);\r
3129                                         StrToIP(&a->SubnetMasks[a->NumIpAddress], s->IpMask.String);\r
3130                                         a->NumIpAddress++;\r
3131                                 }\r
3132                                 s = s->Next;\r
3133                         }\r
3134 \r
3135                         // ゲートウェイ\r
3136                         a->NumGateway = 0;\r
3137                         s = &info->GatewayList;\r
3138                         while (s != NULL)\r
3139                         {\r
3140                                 if (a->NumGateway < MAX_MS_ADAPTER_IP_ADDRESS)\r
3141                                 {\r
3142                                         StrToIP(&a->Gateways[a->NumGateway], s->IpAddress.String);\r
3143                                         a->NumGateway++;\r
3144                                 }\r
3145                                 s = s->Next;\r
3146                         }\r
3147 \r
3148                         // DHCP サーバー\r
3149                         a->UseDhcp = (info->DhcpEnabled == 0 ? false : true);\r
3150                         if (a->UseDhcp)\r
3151                         {\r
3152                                 SYSTEMTIME st;\r
3153 \r
3154                                 StrToIP(&a->DhcpServer, info->DhcpServer.IpAddress.String);\r
3155                                 TimeToSystem(&st, info->LeaseObtained);\r
3156                                 a->DhcpLeaseStart = SystemToUINT64(&st);\r
3157 \r
3158                                 TimeToSystem(&st, info->LeaseExpires);\r
3159                                 a->DhcpLeaseExpires = SystemToUINT64(&st);\r
3160                         }\r
3161 \r
3162                         // WINS サーバー\r
3163                         a->UseWins = info->HaveWins;\r
3164                         if (a->UseWins)\r
3165                         {\r
3166                                 StrToIP(&a->PrimaryWinsServer, info->PrimaryWinsServer.IpAddress.String);\r
3167                                 StrToIP(&a->SecondaryWinsServer, info->SecondaryWinsServer.IpAddress.String);\r
3168                         }\r
3169 \r
3170                         StrCpy(a->Guid, sizeof(a->Guid), info->AdapterName);\r
3171 \r
3172                         a->Info = true;\r
3173 \r
3174                         break;\r
3175                 }\r
3176 \r
3177                 info = info->Next;\r
3178         }\r
3179 \r
3180         Free(info_top);\r
3181 }\r
3182 \r
3183 // アダプタリストの生成\r
3184 MS_ADAPTER_LIST *MsCreateAdapterList()\r
3185 {\r
3186         return MsCreateAdapterListEx(false);\r
3187 }\r
3188 MS_ADAPTER_LIST *MsCreateAdapterListEx(bool no_info)\r
3189 {\r
3190         MS_ADAPTER_LIST *ret;\r
3191 \r
3192         if (no_info)\r
3193         {\r
3194                 ret = MsCreateAdapterListInnerEx(true);\r
3195 \r
3196                 return ret;\r
3197         }\r
3198 \r
3199         Lock(lock_adapter_list);\r
3200         {\r
3201                 MS_ADAPTER_LIST *old = last_adapter_list;\r
3202                 UINT i;\r
3203 \r
3204                 // 新しくアダプタリストを取ってくる\r
3205                 ret = MsCreateAdapterListInner();\r
3206 \r
3207                 if (ret == NULL)\r
3208                 {\r
3209                         Unlock(lock_adapter_list);\r
3210                         return NULL;\r
3211                 }\r
3212 \r
3213                 // 取ってきたアダプタリストの各エントリについて、前回取得したものが\r
3214                 // 存在するかどうかチェックする\r
3215                 for (i = 0;i < ret->Num;i++)\r
3216                 {\r
3217                         UINT j;\r
3218                         for (j = 0;j < old->Num;j++)\r
3219                         {\r
3220                                 MS_ADAPTER *o = old->Adapters[j];\r
3221                                 MS_ADAPTER *n = ret->Adapters[i];\r
3222 \r
3223                                 if (StrCmpi(o->Title, n->Title) == 0)\r
3224                                 {\r
3225                                         // 古いもののほうが値が小さい場合、インクリメントする\r
3226                                         CHECK_32BIT_OVERFLOW(o->RecvBytes, n->RecvBytes);\r
3227                                         CHECK_32BIT_OVERFLOW(o->RecvPacketsBroadcast, n->RecvPacketsBroadcast);\r
3228                                         CHECK_32BIT_OVERFLOW(o->RecvPacketsUnicast, n->RecvPacketsUnicast);\r
3229                                         CHECK_32BIT_OVERFLOW(o->SendBytes, n->SendBytes);\r
3230                                         CHECK_32BIT_OVERFLOW(o->SendPacketsBroadcast, n->SendPacketsBroadcast);\r
3231                                         CHECK_32BIT_OVERFLOW(o->SendPacketsUnicast, n->SendPacketsUnicast);\r
3232                                         break;\r
3233                                 }\r
3234                         }\r
3235                 }\r
3236 \r
3237                 // 古いアダプタリストを解放する\r
3238                 MsFreeAdapterList(old);\r
3239 \r
3240                 // 新しく取得したアダプタリストのクローンを保存しておく\r
3241                 last_adapter_list = MsCloneAdapterList(ret);\r
3242         }\r
3243         Unlock(lock_adapter_list);\r
3244 \r
3245         return ret;\r
3246 }\r
3247 \r
3248 // アダプタリストモジュールの初期化\r
3249 void MsInitAdapterListModule()\r
3250 {\r
3251         lock_adapter_list = NewLock(NULL);\r
3252 \r
3253         last_adapter_list = MsCreateAdapterListInner();\r
3254 }\r
3255 \r
3256 // アダプタリストモジュールの解放\r
3257 void MsFreeAdapterListModule()\r
3258 {\r
3259         if (last_adapter_list != NULL)\r
3260         {\r
3261                 MsFreeAdapterList(last_adapter_list);\r
3262                 last_adapter_list = NULL;\r
3263         }\r
3264 \r
3265         DeleteLock(lock_adapter_list);\r
3266         lock_adapter_list = NULL;\r
3267 }\r
3268 \r
3269 // アダプタリストのクローン\r
3270 MS_ADAPTER_LIST *MsCloneAdapterList(MS_ADAPTER_LIST *o)\r
3271 {\r
3272         MS_ADAPTER_LIST *ret;\r
3273         UINT i;\r
3274         // 引数チェック\r
3275         if (o == NULL)\r
3276         {\r
3277                 return NULL;\r
3278         }\r
3279 \r
3280         ret = ZeroMalloc(sizeof(MS_ADAPTER_LIST));\r
3281         ret->Num = o->Num;\r
3282         ret->Adapters = ZeroMalloc(sizeof(MS_ADAPTER *) * ret->Num);\r
3283 \r
3284         for (i = 0;i < ret->Num;i++)\r
3285         {\r
3286                 ret->Adapters[i] = ZeroMalloc(sizeof(MS_ADAPTER));\r
3287                 Copy(ret->Adapters[i], o->Adapters[i], sizeof(MS_ADAPTER));\r
3288         }\r
3289 \r
3290         return ret;\r
3291 }\r
3292 \r
3293 // アダプタのクローン\r
3294 MS_ADAPTER *MsCloneAdapter(MS_ADAPTER *a)\r
3295 {\r
3296         MS_ADAPTER *ret;\r
3297         // 引数チェック\r
3298         if (a == NULL)\r
3299         {\r
3300                 return NULL;\r
3301         }\r
3302 \r
3303         ret = ZeroMalloc(sizeof(MS_ADAPTER));\r
3304         Copy(ret, a, sizeof(MS_ADAPTER));\r
3305 \r
3306         return ret;\r
3307 }\r
3308 \r
3309 // アダプタリストの作成\r
3310 MS_ADAPTER_LIST *MsCreateAdapterListInner()\r
3311 {\r
3312         return MsCreateAdapterListInnerEx(false);\r
3313 }\r
3314 MS_ADAPTER_LIST *MsCreateAdapterListInnerEx(bool no_info)\r
3315 {\r
3316         LIST *o;\r
3317         UINT i;\r
3318         UINT retcode;\r
3319         MIB_IFTABLE *table;\r
3320         UINT table_size = sizeof(MIB_IFTABLE);\r
3321         MS_ADAPTER_LIST *ret;\r
3322 \r
3323         table = ZeroMalloc(table_size);\r
3324 \r
3325         if (w32net->GetIfTable == NULL)\r
3326         {\r
3327                 return ZeroMalloc(sizeof(MS_ADAPTER_LIST));\r
3328         }\r
3329 \r
3330         retcode = w32net->GetIfTable(table, &table_size, TRUE);\r
3331         if (retcode == ERROR_INSUFFICIENT_BUFFER || retcode == ERROR_BUFFER_OVERFLOW)\r
3332         {\r
3333                 Free(table);\r
3334                 table_size *= 2;\r
3335                 table = ZeroMalloc(table_size);\r
3336                 if (w32net->GetIfTable(table, &table_size, TRUE) != NO_ERROR)\r
3337                 {\r
3338                         Free(table);\r
3339                         return NULL;\r
3340                 }\r
3341         }\r
3342         else if (retcode != NO_ERROR)\r
3343         {\r
3344                 Free(table);\r
3345                 return NULL;\r
3346         }\r
3347 \r
3348         o = NewListFast(NULL);\r
3349 \r
3350         for (i = 0;i < table->dwNumEntries;i++)\r
3351         {\r
3352                 MIB_IFROW *r = &table->table[i];\r
3353                 char title[MAX_PATH];\r
3354                 UINT num = 0;\r
3355                 MS_ADAPTER *a;\r
3356                 UINT j;\r
3357 \r
3358                 //if (r->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED || r->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)\r
3359                 {\r
3360                         //if (r->dwType & IF_TYPE_ETHERNET_CSMACD)\r
3361                         {\r
3362                                 for (j = 1;;j++)\r
3363                                 {\r
3364                                         UINT k;\r
3365                                         bool exists;\r
3366                                         if (j == 1)\r
3367                                         {\r
3368                                                 StrCpy(title, sizeof(title), (char *)r->bDescr);\r
3369                                         }\r
3370                                         else\r
3371                                         {\r
3372                                                 Format(title, sizeof(title), "%s (%u)", (char *)r->bDescr, j);\r
3373                                         }\r
3374 \r
3375                                         exists = false;\r
3376 \r
3377                                         for (k = 0;k < LIST_NUM(o);k++)\r
3378                                         {\r
3379                                                 MS_ADAPTER *a = LIST_DATA(o, k);\r
3380 \r
3381                                                 if (StrCmpi(a->Title, title) == 0)\r
3382                                                 {\r
3383                                                         exists = true;\r
3384                                                         break;\r
3385                                                 }\r
3386                                         }\r
3387 \r
3388                                         if (exists == false)\r
3389                                         {\r
3390                                                 break;\r
3391                                         }\r
3392                                 }\r
3393 \r
3394                                 a = ZeroMalloc(sizeof(MS_ADAPTER));\r
3395 \r
3396                                 // アダプタ情報作成\r
3397                                 StrCpy(a->Title, sizeof(a->Title), title);\r
3398                                 a->Index = r->dwIndex;\r
3399                                 a->Type = r->dwType;\r
3400                                 a->Status = r->dwOperStatus;\r
3401                                 a->Mtu = r->dwMtu;\r
3402                                 a->Speed = r->dwSpeed;\r
3403                                 a->AddressSize = MIN(sizeof(a->Address), r->dwPhysAddrLen);\r
3404                                 Copy(a->Address, r->bPhysAddr, a->AddressSize);\r
3405                                 a->RecvBytes = r->dwInOctets;\r
3406                                 a->RecvPacketsBroadcast = r->dwInNUcastPkts;\r
3407                                 a->RecvPacketsUnicast = r->dwInUcastPkts;\r
3408                                 a->SendBytes = r->dwOutOctets;\r
3409                                 a->SendPacketsBroadcast = r->dwOutNUcastPkts;\r
3410                                 a->SendPacketsUnicast = r->dwOutUcastPkts;\r
3411 \r
3412                                 // TCP/IP 情報取得\r
3413                                 if (no_info == false)\r
3414                                 {\r
3415                                         MsGetAdapterTcpIpInformation(a);\r
3416                                 }\r
3417 \r
3418                                 Add(o, a);\r
3419                         }\r
3420                 }\r
3421         }\r
3422 \r
3423         ret = ZeroMalloc(sizeof(MS_ADAPTER_LIST));\r
3424         ret->Num = LIST_NUM(o);\r
3425         ret->Adapters = ToArray(o);\r
3426 \r
3427         ReleaseList(o);\r
3428         Free(table);\r
3429 \r
3430         return ret;\r
3431 }\r
3432 \r
3433 // アダプタリストの解放\r
3434 void MsFreeAdapterList(MS_ADAPTER_LIST *o)\r
3435 {\r
3436         UINT i;\r
3437         // 引数チェック\r
3438         if (o == NULL)\r
3439         {\r
3440                 return;\r
3441         }\r
3442 \r
3443         for (i = 0;i < o->Num;i++)\r
3444         {\r
3445                 MsFreeAdapter(o->Adapters[i]);\r
3446         }\r
3447         Free(o->Adapters);\r
3448 \r
3449         Free(o);\r
3450 }\r
3451 \r
3452 // アダプタ情報の解放\r
3453 void MsFreeAdapter(MS_ADAPTER *a)\r
3454 {\r
3455         // 引数チェック\r
3456         if (a == NULL)\r
3457         {\r
3458                 return;\r
3459         }\r
3460 \r
3461         Free(a);\r
3462 }\r
3463 \r
3464 // アダプタの状態文字列を取得する\r
3465 wchar_t *MsGetAdapterStatusStr(UINT status)\r
3466 {\r
3467         wchar_t *ret;\r
3468 \r
3469         switch (status)\r
3470         {\r
3471         case MIB_IF_OPER_STATUS_NON_OPERATIONAL:\r
3472                 ret = _UU("MS_NON_OPERATIONAL");\r
3473                 break;\r
3474 \r
3475         case MIB_IF_OPER_STATUS_UNREACHABLE:\r
3476                 ret = _UU("MS_UNREACHABLE");\r
3477                 break;\r
3478 \r
3479         case MIB_IF_OPER_STATUS_DISCONNECTED:\r
3480                 ret = _UU("MS_DISCONNECTED");\r
3481                 break;\r
3482 \r
3483         case MIB_IF_OPER_STATUS_CONNECTING:\r
3484                 ret = _UU("MS_CONNECTING");\r
3485                 break;\r
3486 \r
3487         case MIB_IF_OPER_STATUS_CONNECTED:\r
3488                 ret = _UU("MS_CONNECTED");\r
3489                 break;\r
3490 \r
3491         default:\r
3492                 ret = _UU("MS_OPERATIONAL");\r
3493                 break;\r
3494         }\r
3495 \r
3496         return ret;\r
3497 }\r
3498 \r
3499 // アダプタの種類文字列を取得する\r
3500 wchar_t *MsGetAdapterTypeStr(UINT type)\r
3501 {\r
3502         wchar_t *ret;\r
3503 \r
3504         switch (type)\r
3505         {\r
3506         case MIB_IF_TYPE_ETHERNET:\r
3507                 ret = _UU("MS_ETHERNET");\r
3508                 break;\r
3509 \r
3510         case MIB_IF_TYPE_TOKENRING:\r
3511                 ret = _UU("MS_TOKENRING");\r
3512                 break;\r
3513 \r
3514         case MIB_IF_TYPE_FDDI:\r
3515                 ret = _UU("MS_FDDI");\r
3516                 break;\r
3517 \r
3518         case MIB_IF_TYPE_PPP:\r
3519                 ret = _UU("MS_PPP");\r
3520                 break;\r
3521 \r
3522         case MIB_IF_TYPE_LOOPBACK:\r
3523                 ret = _UU("MS_LOOPBACK");\r
3524                 break;\r
3525 \r
3526         case MIB_IF_TYPE_SLIP:\r
3527                 ret = _UU("MS_SLIP");\r
3528                 break;\r
3529 \r
3530         default:\r
3531                 ret = _UU("MS_OTHER");\r
3532                 break;\r
3533         }\r
3534 \r
3535         return ret;\r
3536 }\r
3537 \r
3538 // 自分自身の EXE の自分以外のインスタンスをすべて終了する\r
3539 void MsKillOtherInstance()\r
3540 {\r
3541         MsKillOtherInstanceEx(NULL);\r
3542 }\r
3543 void MsKillOtherInstanceEx(char *exclude_svcname)\r
3544 {\r
3545         UINT me, i;\r
3546         wchar_t me_path[MAX_PATH];\r
3547         wchar_t me_path_short[MAX_PATH];\r
3548         LIST *o = MsGetProcessList();\r
3549         UINT e_procid = 0;\r
3550         UINT e_procid2 = 0;\r
3551 \r
3552         if (exclude_svcname != NULL)\r
3553         {\r
3554                 e_procid = MsReadCallingServiceManagerProcessId(exclude_svcname, false);\r
3555                 e_procid2 = MsReadCallingServiceManagerProcessId(exclude_svcname, true);\r
3556         }\r
3557 \r
3558         me = MsGetProcessId();\r
3559 \r
3560         MsGetCurrentProcessExeNameW(me_path, sizeof(me_path));\r
3561         MsGetShortPathNameW(me_path, me_path_short, sizeof(me_path_short));\r
3562 \r
3563         for (i = 0;i < LIST_NUM(o);i++)\r
3564         {\r
3565                 MS_PROCESS *p = LIST_DATA(o, i);\r
3566                 if (p->ProcessId != me)\r
3567                 {\r
3568                         if ((e_procid == 0 || (e_procid != p->ProcessId)) && (e_procid2 == 0 || (e_procid2 != p->ProcessId)))\r
3569                         {\r
3570                                 wchar_t tmp[MAX_PATH];\r
3571                                 MsGetShortPathNameW(p->ExeFilenameW, tmp, sizeof(tmp));\r
3572                                 if (UniStrCmpi(me_path_short, tmp) == 0)\r
3573                                 {\r
3574                                         MsKillProcess(p->ProcessId);\r
3575                                 }\r
3576                         }\r
3577                 }\r
3578         }\r
3579 \r
3580         MsFreeProcessList(o);\r
3581 }\r
3582 \r
3583 // 短いファイル名を取得する\r
3584 bool MsGetShortPathNameA(char *long_path, char *short_path, UINT short_path_size)\r
3585 {\r
3586         // 引数チェック\r
3587         if (long_path == NULL || short_path == NULL)\r
3588         {\r
3589                 return false;\r
3590         }\r
3591 \r
3592         if (GetShortPathNameA(long_path, short_path, short_path_size) == 0)\r
3593         {\r
3594                 StrCpy(short_path, short_path_size, long_path);\r
3595                 return false;\r
3596         }\r
3597 \r
3598         return true;\r
3599 }\r
3600 bool MsGetShortPathNameW(wchar_t *long_path, wchar_t *short_path, UINT short_path_size)\r
3601 {\r
3602         // 引数チェック\r
3603         if (long_path == NULL || short_path == NULL)\r
3604         {\r
3605                 return false;\r
3606         }\r
3607 \r
3608         if (IsNt() == false)\r
3609         {\r
3610                 char short_path_a[MAX_SIZE];\r
3611                 char long_path_a[MAX_SIZE];\r
3612                 bool ret;\r
3613 \r
3614                 UniToStr(long_path_a, sizeof(long_path_a), long_path);\r
3615 \r
3616                 ret = MsGetShortPathNameA(long_path_a, short_path_a, sizeof(short_path_a));\r
3617 \r
3618                 StrToUni(short_path, short_path_size, short_path_a);\r
3619 \r
3620                 return ret;\r
3621         }\r
3622 \r
3623         if (GetShortPathNameW(long_path, short_path, short_path_size) == 0)\r
3624         {\r
3625                 UniStrCpy(short_path, short_path_size, long_path);\r
3626                 return false;\r
3627         }\r
3628 \r
3629         return true;\r
3630 }\r
3631 \r
3632 // 指定したプロセスの強制終了\r
3633 bool MsKillProcess(UINT id)\r
3634 {\r
3635         HANDLE h;\r
3636         // 引数チェック\r
3637         if (id == 0)\r
3638         {\r
3639                 return false;\r
3640         }\r
3641 \r
3642         h = OpenProcess(PROCESS_TERMINATE, FALSE, id);\r
3643         if (h == NULL)\r
3644         {\r
3645                 return false;\r
3646         }\r
3647 \r
3648         if (TerminateProcess(h, 0) == FALSE)\r
3649         {\r
3650                 CloseHandle(h);\r
3651                 return false;\r
3652         }\r
3653 \r
3654         CloseHandle(h);\r
3655 \r
3656         return true;\r
3657 }\r
3658 \r
3659 // 現在の EXE ファイル名を取得\r
3660 void MsGetCurrentProcessExeName(char *name, UINT size)\r
3661 {\r
3662         UINT id;\r
3663         LIST *o;\r
3664         MS_PROCESS *p;\r
3665         // 引数チェック\r
3666         if (name == NULL)\r
3667         {\r
3668                 return;\r
3669         }\r
3670 \r
3671         id = MsGetCurrentProcessId();\r
3672         o = MsGetProcessList();\r
3673         p = MsSearchProcessById(o, id);\r
3674         if (p != NULL)\r
3675         {\r
3676                 p = MsSearchProcessById(o, id);\r
3677                 StrCpy(name, size, p->ExeFilename);\r
3678         }\r
3679         else\r
3680         {\r
3681                 StrCpy(name, size, MsGetExeFileName());\r
3682         }\r
3683         MsFreeProcessList(o);\r
3684 }\r
3685 void MsGetCurrentProcessExeNameW(wchar_t *name, UINT size)\r
3686 {\r
3687         UINT id;\r
3688         LIST *o;\r
3689         MS_PROCESS *p;\r
3690         // 引数チェック\r
3691         if (name == NULL)\r
3692         {\r
3693                 return;\r
3694         }\r
3695 \r
3696         id = MsGetCurrentProcessId();\r
3697         o = MsGetProcessList();\r
3698         p = MsSearchProcessById(o, id);\r
3699         if (p != NULL)\r
3700         {\r
3701                 p = MsSearchProcessById(o, id);\r
3702                 UniStrCpy(name, size, p->ExeFilenameW);\r
3703         }\r
3704         else\r
3705         {\r
3706                 UniStrCpy(name, size, MsGetExeFileNameW());\r
3707         }\r
3708         MsFreeProcessList(o);\r
3709 }\r
3710 \r
3711 // プロセスをプロセス ID から検索する\r
3712 MS_PROCESS *MsSearchProcessById(LIST *o, UINT id)\r
3713 {\r
3714         MS_PROCESS *p, t;\r
3715         // 引数チェック\r
3716         if (o == NULL)\r
3717         {\r
3718                 return NULL;\r
3719         }\r
3720 \r
3721         Zero(&t, sizeof(t));\r
3722         t.ProcessId = id;\r
3723 \r
3724         p = Search(o, &t);\r
3725 \r
3726         return p;\r
3727 }\r
3728 \r
3729 // プロセスリスト比較\r
3730 int MsCompareProcessList(void *p1, void *p2)\r
3731 {\r
3732         MS_PROCESS *e1, *e2;\r
3733         if (p1 == NULL || p2 == NULL)\r
3734         {\r
3735                 return 0;\r
3736         }\r
3737         e1 = *(MS_PROCESS **)p1;\r
3738         e2 = *(MS_PROCESS **)p2;\r
3739         if (e1 == NULL || e2 == NULL)\r
3740         {\r
3741                 return 0;\r
3742         }\r
3743 \r
3744         if (e1->ProcessId > e2->ProcessId)\r
3745         {\r
3746                 return 1;\r
3747         }\r
3748         else if (e1->ProcessId < e2->ProcessId)\r
3749         {\r
3750                 return -1;\r
3751         }\r
3752         else\r
3753         {\r
3754                 return 0;\r
3755         }\r
3756 }\r
3757 \r
3758 // プロセスリストの表示\r
3759 void MsPrintProcessList(LIST *o)\r
3760 {\r
3761         UINT i;\r
3762         // 引数チェック\r
3763         if (o == NULL)\r
3764         {\r
3765                 return;\r
3766         }\r
3767 \r
3768         for (i = 0;i < LIST_NUM(o);i++)\r
3769         {\r
3770                 MS_PROCESS *p = LIST_DATA(o, i);\r
3771                 UniPrint(L"%-4u: %s\n", p->ProcessId, p->ExeFilenameW);\r
3772         }\r
3773 }\r
3774 \r
3775 // プロセスリストの解放\r
3776 void MsFreeProcessList(LIST *o)\r
3777 {\r
3778         UINT i;\r
3779         // 引数チェック\r
3780         if (o == NULL)\r
3781         {\r
3782                 return;\r
3783         }\r
3784 \r
3785         for (i = 0;i < LIST_NUM(o);i++)\r
3786         {\r
3787                 MS_PROCESS *p = LIST_DATA(o, i);\r
3788                 Free(p);\r
3789         }\r
3790 \r
3791         ReleaseList(o);\r
3792 }\r
3793 \r
3794 // プロセスリストの取得 (WinNT 用)\r
3795 LIST *MsGetProcessListNt()\r
3796 {\r
3797         LIST *o;\r
3798         UINT max = 16384;\r
3799         DWORD *processes;\r
3800         UINT needed, num;\r
3801         UINT i;\r
3802 \r
3803         o = NewListFast(MsCompareProcessList);\r
3804 \r
3805         if (ms->nt->EnumProcesses == NULL)\r
3806         {\r
3807                 return o;\r
3808         }\r
3809 \r
3810         processes = ZeroMalloc(sizeof(DWORD) * max);\r
3811 \r
3812         if (ms->nt->EnumProcesses(processes, sizeof(DWORD) * max, &needed) == FALSE)\r
3813         {\r
3814                 Free(processes);\r
3815                 return NULL;\r
3816         }\r
3817 \r
3818         num = needed / sizeof(DWORD);\r
3819 \r
3820         for (i = 0;i < num;i++)\r
3821         {\r
3822                 UINT id = processes[i];\r
3823                 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,\r
3824                         false, id);\r
3825 \r
3826                 if (h != NULL)\r
3827                 {\r
3828                         HINSTANCE hInst = NULL;\r
3829                         DWORD needed;\r
3830                         if (ms->nt->EnumProcessModules(h, &hInst, sizeof(hInst), &needed))\r
3831                         {\r
3832                                 MS_PROCESS *p = ZeroMalloc(sizeof(MS_PROCESS));\r
3833                                 ms->nt->GetModuleFileNameExA(h, hInst, p->ExeFilename, sizeof(p->ExeFilename) - 1);\r
3834                                 ms->nt->GetModuleFileNameExW(h, hInst, p->ExeFilenameW, sizeof(p->ExeFilenameW) / sizeof(wchar_t) - 1);\r
3835                                 p->ProcessId = id;\r
3836                                 Add(o, p);\r
3837                         }\r
3838                         CloseHandle(h);\r
3839                 }\r
3840         }\r
3841 \r
3842         Sort(o);\r
3843 \r
3844         Free(processes);\r
3845 \r
3846         return o;\r
3847 }\r
3848 \r
3849 // プロセスリストの取得 (Win9x 用)\r
3850 LIST *MsGetProcessList9x()\r
3851 {\r
3852         HANDLE h;\r
3853         LIST *o;\r
3854         HANDLE (WINAPI *CreateToolhelp32Snapshot)(DWORD, DWORD);\r
3855         BOOL (WINAPI *Process32First)(HANDLE, LPPROCESSENTRY32);\r
3856         BOOL (WINAPI *Process32Next)(HANDLE, LPPROCESSENTRY32);\r
3857 \r
3858         CreateToolhelp32Snapshot =\r
3859                 (HANDLE (__stdcall *)(DWORD,DWORD))\r
3860                 GetProcAddress(ms->hKernel32, "CreateToolhelp32Snapshot");\r
3861         Process32First =\r
3862                 (BOOL (__stdcall *)(HANDLE,LPPROCESSENTRY32))\r
3863                 GetProcAddress(ms->hKernel32, "Process32First");\r
3864         Process32Next =\r
3865                 (BOOL (__stdcall *)(HANDLE,LPPROCESSENTRY32))\r
3866                 GetProcAddress(ms->hKernel32, "Process32Next");\r
3867 \r
3868         o = NewListFast(MsCompareProcessList);\r
3869 \r
3870         if (CreateToolhelp32Snapshot != NULL && Process32First != NULL && Process32Next != NULL)\r
3871         {\r
3872                 h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r
3873                 if (h != INVALID_HANDLE_VALUE)\r
3874                 {\r
3875                         PROCESSENTRY32 e;\r
3876                         Zero(&e, sizeof(e));\r
3877                         e.dwSize = sizeof(e);\r
3878 \r
3879                         if (Process32First(h, &e))\r
3880                         {\r
3881                                 while (true)\r
3882                                 {\r
3883                                         MS_PROCESS *p = ZeroMalloc(sizeof(MS_PROCESS));\r
3884                                         StrCpy(p->ExeFilename, sizeof(p->ExeFilename), e.szExeFile);\r
3885                                         StrToUni(p->ExeFilenameW, sizeof(p->ExeFilenameW), p->ExeFilename);\r
3886                                         p->ProcessId = e.th32ProcessID;\r
3887                                         Add(o, p);\r
3888                                         if (Process32Next(h, &e) == false)\r
3889                                         {\r
3890                                                 break;\r
3891                                         }\r
3892                                 }\r
3893                         }\r
3894                         CloseHandle(h);\r
3895                 }\r
3896         }\r
3897 \r
3898         Sort(o);\r
3899 \r
3900         return o;\r
3901 }\r
3902 \r
3903 // プロセスリストの取得\r
3904 LIST *MsGetProcessList()\r
3905 {\r
3906         if (MsIsNt() == false)\r
3907         {\r
3908                 // Windows 9x\r
3909                 return MsGetProcessList9x();\r
3910         }\r
3911         else\r
3912         {\r
3913                 // Windows NT, 2000, XP\r
3914                 return MsGetProcessListNt();\r
3915         }\r
3916 }\r
3917 \r
3918 // 現在のスレッドを 1 つの CPU で動作するように強制する\r
3919 void MsSetThreadSingleCpu()\r
3920 {\r
3921         SetThreadAffinityMask(GetCurrentThread(), 1);\r
3922 }\r
3923 \r
3924 // サウンドの再生\r
3925 void MsPlaySound(char *name)\r
3926 {\r
3927         char tmp[MAX_SIZE];\r
3928         char wav[MAX_SIZE];\r
3929         char *temp;\r
3930         BUF *b;\r
3931         // 引数チェック\r
3932         if (name == NULL)\r
3933         {\r
3934                 return;\r
3935         }\r
3936 \r
3937         Format(tmp, sizeof(tmp), "|%s", name);\r
3938 \r
3939         b = ReadDump(tmp);\r
3940         if (b == NULL)\r
3941         {\r
3942                 return;\r
3943         }\r
3944 \r
3945         temp = MsGetMyTempDir();\r
3946         Format(wav, sizeof(tmp), "%s\\%s", temp, name);\r
3947         DumpBuf(b, wav);\r
3948 \r
3949         PlaySound(wav, NULL, SND_ASYNC | SND_FILENAME | SND_NODEFAULT);\r
3950 \r
3951         FreeBuf(b);\r
3952 }\r
3953 \r
3954 // タスクトレイにアイコンを表示する\r
3955 void MsShowIconOnTray(HWND hWnd, HICON icon, wchar_t *tooltip, UINT msg)\r
3956 {\r
3957         // 引数チェック\r
3958         if (hWnd == NULL || icon == NULL)\r
3959         {\r
3960                 return;\r
3961         }\r
3962 \r
3963         if (MsIsNt() == false)\r
3964         {\r
3965                 Zero(&nid, sizeof(nid));\r
3966                 nid.cbSize = sizeof(nid);\r
3967                 nid.hWnd = hWnd;\r
3968                 nid.uID = 1;\r
3969                 nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;\r
3970                 nid.uCallbackMessage = msg;\r
3971                 nid.hIcon = icon;\r
3972                 UniToStr(nid.szTip, sizeof(nid.szTip), tooltip);\r
3973                 Shell_NotifyIcon(NIM_ADD, &nid);\r
3974         }\r
3975         else\r
3976         {\r
3977                 Zero(&nid_nt, sizeof(nid_nt));\r
3978                 nid_nt.cbSize = sizeof(nid_nt);\r
3979                 nid_nt.hWnd = hWnd;\r
3980                 nid_nt.uID = 1;\r
3981                 nid_nt.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;\r
3982                 nid_nt.uCallbackMessage = msg;\r
3983                 nid_nt.hIcon = icon;\r
3984                 UniStrCpy(nid_nt.szTip, sizeof(nid_nt.szTip), tooltip);\r
3985                 Shell_NotifyIconW(NIM_ADD, &nid_nt);\r
3986         }\r
3987 \r
3988         tray_inited = true;\r
3989 }\r
3990 \r
3991 // タスクトレイが初期化されているかどうか確認する\r
3992 bool MsIsTrayInited()\r
3993 {\r
3994         return tray_inited;\r
3995 }\r
3996 \r
3997 // タスクトレイのアイコンを復元する\r
3998 void MsRestoreIconOnTray()\r
3999 {\r
4000         if (tray_inited == false)\r
4001         {\r
4002                 return;\r
4003         }\r
4004 \r
4005         if (MsIsNt() == false)\r
4006         {\r
4007                 Shell_NotifyIcon(NIM_ADD, &nid);\r
4008         }\r
4009         else\r
4010         {\r
4011                 Shell_NotifyIconW(NIM_ADD, &nid_nt);\r
4012         }\r
4013 }\r
4014 \r
4015 // タスクトレイのアイコンを変更する (いけー)\r
4016 void MsChangeIconOnTrayEx2(void *icon, wchar_t *tooltip, wchar_t *info_title, wchar_t *info, UINT info_flags)\r
4017 {\r
4018         MsChangeIconOnTrayEx((HICON)icon, tooltip, info_title, info, info_flags);\r
4019 }\r
4020 \r
4021 // タスクトレイのアイコンを変更する\r
4022 void MsChangeIconOnTray(HICON icon, wchar_t *tooltip)\r
4023 {\r
4024         MsChangeIconOnTrayEx(icon, tooltip, NULL, NULL, NIIF_NONE);\r
4025 }\r
4026 void MsChangeIconOnTrayEx(HICON icon, wchar_t *tooltip, wchar_t *info_title, wchar_t *info, UINT info_flags)\r
4027 {\r
4028         bool changed = false;\r
4029 \r
4030         if (tray_inited == false)\r
4031         {\r
4032                 return;\r
4033         }\r
4034 \r
4035         if (icon != NULL)\r
4036         {\r
4037                 if (MsIsNt() == false)\r
4038                 {\r
4039                         if (nid.hIcon != icon)\r
4040                         {\r
4041                                 changed = true;\r
4042                                 nid.hIcon = icon;\r
4043                         }\r
4044                 }\r
4045                 else\r
4046                 {\r
4047                         if (nid_nt.hIcon != icon)\r
4048                         {\r
4049                                 changed = true;\r
4050                                 nid_nt.hIcon = icon;\r
4051                         }\r
4052                 }\r
4053         }\r
4054 \r
4055         if (tooltip != NULL)\r
4056         {\r
4057                 if (MsIsNt() == false)\r
4058                 {\r
4059                         char tmp[MAX_SIZE];\r
4060 \r
4061                         UniToStr(tmp, sizeof(tmp), tooltip);\r
4062 \r
4063                         if (StrCmp(nid.szTip, tmp) != 0)\r
4064                         {\r
4065                                 StrCpy(nid.szTip, sizeof(nid.szTip), tmp);\r
4066                                 changed = true;\r
4067                         }\r
4068                 }\r
4069                 else\r
4070                 {\r
4071                         wchar_t tmp[MAX_SIZE];\r
4072 \r
4073                         UniStrCpy(tmp, sizeof(tmp), tooltip);\r
4074 \r
4075                         if (UniStrCmp(nid_nt.szTip, tmp) != 0)\r
4076                         {\r
4077                                 UniStrCpy(nid_nt.szTip, sizeof(nid_nt.szTip), tmp);\r
4078                                 changed = true;\r
4079                         }\r
4080                 }\r
4081         }\r
4082 \r
4083         if (info_title != NULL && info != NULL)\r
4084         {\r
4085                 if (MsIsNt() == false)\r
4086                 {\r
4087                         char tmp1[MAX_SIZE];\r
4088                         char tmp2[MAX_PATH];\r
4089 \r
4090                         UniToStr(tmp1, sizeof(tmp1), info_title);\r
4091                         UniToStr(tmp2, sizeof(tmp2), info);\r
4092 \r
4093                         if (StrCmp(nid.szInfo, tmp1) != 0 ||\r
4094                                 StrCmp(nid.szInfoTitle, tmp2) != 0)\r
4095                         {\r
4096                                 StrCpy(nid.szInfo, sizeof(nid.szInfo), tmp1);\r
4097                                 StrCpy(nid.szInfoTitle, sizeof(nid.szInfoTitle), tmp2);\r
4098                                 nid.dwInfoFlags = info_flags;\r
4099 \r
4100                                 changed = true;\r
4101                         }\r
4102                 }\r
4103                 else\r
4104                 {\r
4105                         wchar_t tmp1[MAX_SIZE];\r
4106                         wchar_t tmp2[MAX_PATH];\r
4107 \r
4108                         UniStrCpy(tmp1, sizeof(tmp1), info_title);\r
4109                         UniStrCpy(tmp2, sizeof(tmp2), info);\r
4110 \r
4111                         if (UniStrCmp(nid_nt.szInfo, tmp1) != 0 ||\r
4112                                 UniStrCmp(nid_nt.szInfoTitle, tmp2) != 0)\r
4113                         {\r
4114                                 UniStrCpy(nid_nt.szInfo, sizeof(nid_nt.szInfo), tmp1);\r
4115                                 UniStrCpy(nid_nt.szInfoTitle, sizeof(nid_nt.szInfoTitle), tmp2);\r
4116                                 nid_nt.dwInfoFlags = info_flags;\r
4117 \r
4118                                 changed = true;\r
4119                         }\r
4120                 }\r
4121         }\r
4122 \r
4123         if (changed)\r
4124         {\r
4125                 if (MsIsNt() == false)\r
4126                 {\r
4127                         Shell_NotifyIcon(NIM_MODIFY, &nid);\r
4128                 }\r
4129                 else\r
4130                 {\r
4131                         Shell_NotifyIconW(NIM_MODIFY, &nid_nt);\r
4132                 }\r
4133         }\r
4134 }\r
4135 \r
4136 // タスクトレイのアイコンを削除する\r
4137 void MsHideIconOnTray()\r
4138 {\r
4139         if (MsIsNt() == false)\r
4140         {\r
4141                 Shell_NotifyIcon(NIM_DELETE, &nid);\r
4142         }\r
4143         else\r
4144         {\r
4145                 Shell_NotifyIconW(NIM_DELETE, &nid_nt);\r
4146         }\r
4147 \r
4148         tray_inited = false;\r
4149 }\r
4150 \r
4151 // メニュー項目の挿入\r
4152 bool MsInsertMenu(HMENU hMenu, UINT pos, UINT flags, UINT_PTR id_new_item, wchar_t *lp_new_item)\r
4153 {\r
4154         bool ret;\r
4155 \r
4156         if (MsIsNt())\r
4157         {\r
4158                 ret = InsertMenuW(hMenu, pos, flags, id_new_item, lp_new_item);\r
4159         }\r
4160         else\r
4161         {\r
4162                 char *s = CopyUniToStr(lp_new_item);\r
4163                 ret = InsertMenuA(hMenu, pos, flags, id_new_item, s);\r
4164                 Free(s);\r
4165         }\r
4166 \r
4167         return ret;\r
4168 }\r
4169 \r
4170 // メニュー項目の追加\r
4171 bool MsAppendMenu(HMENU hMenu, UINT flags, UINT_PTR id, wchar_t *str)\r
4172 {\r
4173         bool ret;\r
4174 \r
4175         if (MsIsNt())\r
4176         {\r
4177                 ret = AppendMenuW(hMenu, flags, id, str);\r
4178         }\r
4179         else\r
4180         {\r
4181                 char *s = CopyUniToStr(str);\r
4182                 ret = AppendMenuA(hMenu, flags, id, s);\r
4183                 Free(s);\r
4184         }\r
4185 \r
4186         return ret;\r
4187 }\r
4188 \r
4189 // メニュー表示\r
4190 void MsUserModeTrayMenu(HWND hWnd)\r
4191 {\r
4192         HMENU h;\r
4193         POINT p;\r
4194         wchar_t tmp[MAX_SIZE];\r
4195         wchar_t caption[MAX_SIZE];\r
4196         // 引数チェック\r
4197         if (hWnd == NULL)\r
4198         {\r
4199                 return;\r
4200         }\r
4201 \r
4202         // メニューを作成する\r
4203         h = CreatePopupMenu();\r
4204         MsAppendMenu(h, MF_ENABLED | MF_STRING, 10001, _UU("SVC_USERMODE_MENU_1"));\r
4205         MsAppendMenu(h, MF_SEPARATOR, 10002, NULL);\r
4206 \r
4207         if (MsIsNt())\r
4208         {\r
4209                 GetWindowTextW(hWnd, caption, sizeof(caption));\r
4210         }\r
4211         else\r
4212         {\r
4213                 char tmp[MAX_SIZE];\r
4214                 GetWindowTextA(hWnd, tmp, sizeof(tmp));\r
4215                 StrToUni(caption, sizeof(caption), tmp);\r
4216         }\r
4217 \r
4218         UniFormat(tmp, sizeof(tmp), _UU("SVC_USERMODE_MENU_2"), caption);\r
4219         MsAppendMenu(h, MF_ENABLED | MF_STRING, 10003, tmp);\r
4220 \r
4221         // メニューを表示する\r
4222         GetCursorPos(&p);\r
4223 \r
4224         SetForegroundWindow(hWnd);\r
4225         TrackPopupMenu(h, TPM_LEFTALIGN, p.x, p.y, 0, hWnd, NULL);\r
4226         PostMessage(hWnd, WM_NULL, 0, 0);\r
4227 \r
4228         DestroyMenu(h);\r
4229 }\r
4230 \r
4231 // ユーザーモード用ウインドウプロシージャ\r
4232 LRESULT CALLBACK MsUserModeWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)\r
4233 {\r
4234         wchar_t tmp[MAX_SIZE];\r
4235         char title[MAX_SIZE];\r
4236         wchar_t title_w[MAX_SIZE];\r
4237         char value_name[MAX_SIZE];\r
4238         static UINT taskbar_msg = 0;\r
4239         // 引数チェック\r
4240         if (hWnd == NULL)\r
4241         {\r
4242                 return 0;\r
4243         }\r
4244 \r
4245         if (msg == taskbar_msg && taskbar_msg != 0)\r
4246         {\r
4247                 // タスクバーが再生成された\r
4248                 if (MsRegReadInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, value_name) == 0 &&\r
4249                         service_for_9x_mode == false)\r
4250                 {\r
4251                         MsRestoreIconOnTray();\r
4252                 }\r
4253         }\r
4254 \r
4255         switch (msg)\r
4256         {\r
4257         case WM_ENDSESSION:\r
4258                 // 再開\r
4259                 if (wParam == false)\r
4260                 {\r
4261                         break;\r
4262                 }\r
4263         case WM_CREATE:\r
4264                 // 開始\r
4265                 exiting = false;\r
4266                 g_start();\r
4267                 GetWindowText(hWnd, title, sizeof(title));\r
4268                 StrToUni(title_w, sizeof(title_w), title);\r
4269                 UniFormat(tmp, sizeof(tmp), _UU("SVC_TRAY_TOOLTIP"), title);\r
4270 \r
4271                 if (taskbar_msg == 0)\r
4272                 {\r
4273                         taskbar_msg = RegisterWindowMessage("TaskbarCreated");\r
4274                 }\r
4275 \r
4276                 Format(value_name, sizeof(value_name), SVC_HIDETRAY_REG_VALUE, title_w);\r
4277                 if (MsRegReadInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, value_name) == 0 &&\r
4278                         service_for_9x_mode == false)\r
4279                 {\r
4280                         MsShowIconOnTray(hWnd, tray_icon, tmp, WM_APP + 33);\r
4281                 }\r
4282 \r
4283                 break;\r
4284         case WM_APP + 33:\r
4285                 if (wParam == 1)\r
4286                 {\r
4287                         // タスクトレイのアイコンに対する操作\r
4288                         switch (lParam)\r
4289                         {\r
4290                         case WM_RBUTTONDOWN:\r
4291                                 // 右クリック\r
4292                                 MsUserModeTrayMenu(hWnd);\r
4293                                 break;\r
4294                         case WM_LBUTTONDBLCLK:\r
4295                                 // 左ダブルクリック\r
4296                                 break;\r
4297                         }\r
4298                 }\r
4299                 break;\r
4300         case WM_LBUTTONDOWN:\r
4301                 MsUserModeTrayMenu(hWnd);\r
4302                 break;\r
4303         case WM_QUERYENDSESSION:\r
4304                 if (exiting == false)\r
4305                 {\r
4306                         exiting = true;\r
4307                         MsHideIconOnTray();\r
4308                         g_stop();\r
4309                         DestroyWindow(hWnd);\r
4310                 }\r
4311                 return TRUE;\r
4312         case WM_CLOSE:\r
4313                 // 停止\r
4314                 if (exiting == false)\r
4315                 {\r
4316                         exiting = true;\r
4317                         g_stop();\r
4318                         MsHideIconOnTray();\r
4319                         DestroyWindow(hWnd);\r
4320                 }\r
4321                 break;\r
4322         case WM_DESTROY:\r
4323                 wnd_end = true;\r
4324                 break;\r
4325         case WM_COMMAND:\r
4326                 switch (wParam)\r
4327                 {\r
4328                 case 10001:\r
4329                         GetWindowText(hWnd, title, sizeof(title));\r
4330                         StrToUni(title_w, sizeof(title_w), title);\r
4331                         // 確認メッセージの表示\r
4332                         if (MsgBoxEx(hWnd, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2 |\r
4333                                 MB_SYSTEMMODAL, _UU("SVC_HIDE_TRAY_MSG"), title, title) == IDOK)\r
4334                         {\r
4335                                 char tmp[MAX_SIZE];\r
4336                                 Format(tmp, sizeof(tmp), SVC_HIDETRAY_REG_VALUE, title_w);\r
4337                                 // レジストリに書き込む\r
4338                                 MsRegWriteInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, tmp, 1);\r
4339                                 // アイコンを消す\r
4340                                 MsHideIconOnTray();\r
4341                         }\r
4342                         break;\r
4343                 case 10003:\r
4344                         SendMessage(hWnd, WM_CLOSE, 0, 0);\r
4345                         break;\r
4346                 }\r
4347                 break;\r
4348         }\r
4349         return DefWindowProc(hWnd, msg, wParam, lParam);\r
4350 }\r
4351 \r
4352 // PenCore.dll の名前の取得\r
4353 char *MsGetPenCoreDllFileName()\r
4354 {\r
4355         return PENCORE_DLL_NAME;\r
4356 }\r
4357 \r
4358 // これがユーザーモードかどうか取得\r
4359 bool MsIsUserMode()\r
4360 {\r
4361         return is_usermode;\r
4362 }\r
4363 \r
4364 // サービス側からユーザーモードの終了を指示\r
4365 void MsStopUserModeFromService()\r
4366 {\r
4367         if (hWndUsermode != NULL)\r
4368         {\r
4369                 PostMessage(hWndUsermode, WM_CLOSE, 0, 0);\r
4370         }\r
4371 }\r
4372 \r
4373 // テストのみ実行 (デバッグ用)\r
4374 void MsTestOnly()\r
4375 {\r
4376         g_start();\r
4377         GetLine(NULL, 0);\r
4378         g_stop();\r
4379 \r
4380         _exit(0);\r
4381 }\r
4382 \r
4383 // ユーザーモードとして起動\r
4384 void MsUserMode(char *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon)\r
4385 {\r
4386         wchar_t *title_w = CopyStrToUni(title);\r
4387 \r
4388         MsUserModeW(title_w, start, stop, icon);\r
4389 \r
4390         Free(title_w);\r
4391 }\r
4392 void MsUserModeW(wchar_t *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon)\r
4393 {\r
4394         WNDCLASS wc;\r
4395         HINSTANCE hDll;\r
4396         HWND hWnd;\r
4397         MSG msg;\r
4398         INSTANCE *inst;\r
4399         char title_a[MAX_PATH];\r
4400         // 引数チェック\r
4401         if (title == NULL || start == NULL || stop == NULL)\r
4402         {\r
4403                 return;\r
4404         }\r
4405 \r
4406         UniToStr(title_a, sizeof(title_a), title);\r
4407 \r
4408         is_usermode = true;\r
4409         g_start = start;\r
4410         g_stop = stop;\r
4411 \r
4412         inst = NewSingleInstance(NULL);\r
4413         if (inst == NULL)\r
4414         {\r
4415                 if (service_for_9x_mode == false)\r
4416                 {\r
4417                         // Win9x サービスモードの場合はエラーを表示しない\r
4418                         MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_USERMODE_MUTEX"), ms->ExeFileNameW);\r
4419                 }\r
4420                 return;\r
4421         }\r
4422 \r
4423         if (Is64())\r
4424         {\r
4425                 hDll = MsLoadLibraryAsDataFile(MsGetPenCoreDllFileName());\r
4426         }\r
4427         else\r
4428         {\r
4429                 hDll = MsLoadLibrary(MsGetPenCoreDllFileName());\r
4430         }\r
4431 \r
4432         // アイコン読み込み\r
4433         tray_icon = LoadImage(hDll, MAKEINTRESOURCE(icon), IMAGE_ICON, 16, 16,\r
4434                 (MsIsNt() ? LR_SHARED : 0) | LR_VGACOLOR);\r
4435 \r
4436         // メインウインドウの作成\r
4437         Zero(&wc, sizeof(wc));\r
4438         wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);\r
4439         wc.hCursor = LoadCursor(NULL,IDC_ARROW);\r
4440         wc.hIcon = LoadIcon(hDll, MAKEINTRESOURCE(icon));\r
4441         wc.hInstance = ms->hInst;\r
4442         wc.lpfnWndProc = MsUserModeWindowProc;\r
4443         wc.lpszClassName = title_a;\r
4444         if (RegisterClass(&wc) == 0)\r
4445         {\r
4446                 return;\r
4447         }\r
4448 \r
4449         hWnd = CreateWindow(title_a, title_a, WS_OVERLAPPEDWINDOW,\r
4450                 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,\r
4451                 NULL, NULL, ms->hInst, NULL);\r
4452 \r
4453         if (hWnd == NULL)\r
4454         {\r
4455                 return;\r
4456         }\r
4457 \r
4458         hWndUsermode = hWnd;\r
4459 \r
4460         wnd_end = false;\r
4461         // ウインドウループ\r
4462         while (wnd_end == false)\r
4463         {\r
4464                 GetMessage(&msg, NULL, 0, 0);\r
4465                 TranslateMessage(&msg);\r
4466                 DispatchMessage(&msg);\r
4467         }\r
4468 \r
4469         FreeSingleInstance(inst);\r
4470 \r
4471         hWndUsermode = NULL;\r
4472 \r
4473         // 強制終了して良い\r
4474         _exit(0);\r
4475 }\r
4476 \r
4477 // サービス停止処理メインスレッド\r
4478 void MsServiceStoperMainThread(THREAD *t, void *p)\r
4479 {\r
4480         // 停止処理\r
4481         g_stop();\r
4482 }\r
4483 \r
4484 // サービス停止処理用スレッド\r
4485 void MsServiceStoperThread(THREAD *t, void *p)\r
4486 {\r
4487         THREAD *thread;\r
4488         UINT64 selfkill_timeout = Tick64() + SVC_SELFKILL_TIMEOUT;\r
4489 \r
4490         thread = NewThread(MsServiceStoperMainThread, NULL);\r
4491 \r
4492         // まだ開始中の場合は開始スレッドの終了を待つ\r
4493         while (WaitThread(starter_thread, 250) == false)\r
4494         {\r
4495                 if (Tick64() >= selfkill_timeout)\r
4496                 {\r
4497                         // フリーズ時用の自殺\r
4498                         _exit(0);\r
4499                 }\r
4500                 // 開始処理が完了するまでの間、一定時間ごとに SetServiceStatus を呼び出す\r
4501                 status.dwWin32ExitCode = 0;\r
4502                 status.dwWaitHint = 100000;\r
4503                 status.dwCheckPoint++;\r
4504                 status.dwCurrentState = SERVICE_STOP_PENDING;\r
4505                 ms->nt->SetServiceStatus(ssh, &status);\r
4506         }\r
4507 \r
4508         ReleaseThread(starter_thread);\r
4509         starter_thread = NULL;\r
4510 \r
4511         while (WaitThread(thread, 250) == false)\r
4512         {\r
4513                 if (Tick64() >= selfkill_timeout)\r
4514                 {\r
4515                         // フリーズ時用の自殺\r
4516                         _exit(0);\r
4517                 }\r
4518                 // 停止処理が完了するまでの間、一定時間ごとに SetServiceStatus を呼び出す\r
4519                 status.dwWin32ExitCode = 0;\r
4520                 status.dwWaitHint = 100000;\r
4521                 status.dwCheckPoint++;\r
4522                 status.dwCurrentState = SERVICE_STOP_PENDING;\r
4523                 ms->nt->SetServiceStatus(ssh, &status);\r
4524         }\r
4525 \r
4526         ReleaseThread(thread);\r
4527 \r
4528         // 停止が完了したことを報告する\r
4529         status.dwWin32ExitCode = 0;\r
4530         status.dwWaitHint = 0;\r
4531         status.dwCheckPoint = 0;\r
4532         status.dwCurrentState = SERVICE_STOPPED;\r
4533         ms->nt->SetServiceStatus(ssh, &status);\r
4534 \r
4535         Set(server_stopped_event);\r
4536 }\r
4537 \r
4538 // サービスハンドラ\r
4539 void CALLBACK MsServiceHandler(DWORD opcode)\r
4540 {\r
4541         switch (opcode)\r
4542         {\r
4543         case SERVICE_CONTROL_SHUTDOWN:\r
4544         case SERVICE_CONTROL_STOP:\r
4545                 // 停止要求\r
4546                 status.dwWin32ExitCode = 0;\r
4547                 status.dwWaitHint = 100000;\r
4548                 status.dwCheckPoint = 0;\r
4549                 status.dwCurrentState = SERVICE_STOP_PENDING;\r
4550 \r
4551                 // 停止用スレッドを立てる\r
4552                 service_stopper_thread = NewThread(MsServiceStoperThread, NULL);\r
4553                 break;\r
4554         }\r
4555 \r
4556         ms->nt->SetServiceStatus(ssh, &status);\r
4557 }\r
4558 \r
4559 // サービス開始用スレッド\r
4560 void MsServiceStarterMainThread(THREAD *t, void *p)\r
4561 {\r
4562         // 開始\r
4563         g_start();\r
4564 }\r
4565 \r
4566 // サービスのディスパッチ関数\r
4567 void CALLBACK MsServiceDispatcher(DWORD argc, LPTSTR *argv)\r
4568 {\r
4569         // サービスの準備\r
4570         Zero(&status, sizeof(status));\r
4571         status.dwServiceType = SERVICE_WIN32;\r
4572         status.dwCurrentState = SERVICE_START_PENDING;\r
4573         status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;\r
4574 \r
4575         ssh = ms->nt->RegisterServiceCtrlHandler(g_service_name, MsServiceHandler);\r
4576 \r
4577         if (ssh == NULL)\r
4578         {\r
4579                 Alert("RegisterServiceCtrlHandler() Failed.", "MsServiceDispatcher()");\r
4580                 return;\r
4581         }\r
4582 \r
4583         status.dwWaitHint = 10000;\r
4584         status.dwCheckPoint = 0;\r
4585         status.dwCurrentState = SERVICE_START_PENDING;\r
4586         ms->nt->SetServiceStatus(ssh, &status);\r
4587 \r
4588         // サービス開始用スレッドを作成する\r
4589         starter_thread = NewThread(MsServiceStarterMainThread, NULL);\r
4590 \r
4591         // 開始完了を報告する\r
4592         status.dwWaitHint = 0;\r
4593         status.dwCheckPoint = 0;\r
4594         status.dwCurrentState = SERVICE_RUNNING;\r
4595         ms->nt->SetServiceStatus(ssh, &status);\r
4596 }\r
4597 \r
4598 // サービスとして動作\r
4599 void MsServiceMode(SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)\r
4600 {\r
4601         SERVICE_TABLE_ENTRY dispatch_table[] =\r
4602         {\r
4603                 {"", MsServiceDispatcher},\r
4604                 {NULL, NULL},\r
4605         };\r
4606         INSTANCE *inst;\r
4607         // 引数チェック\r
4608         if (start == NULL || stop == NULL)\r
4609         {\r
4610                 return;\r
4611         }\r
4612 \r
4613         MsSetErrorModeToSilent();\r
4614 \r
4615         g_start = start;\r
4616         g_stop = stop;\r
4617 \r
4618         server_stopped_event = NewEvent();\r
4619 \r
4620         inst = NewSingleInstance(NULL);\r
4621         if (inst == NULL)\r
4622         {\r
4623                 MsgBoxEx(NULL, MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION,\r
4624                         _UU("SVC_SERVICE_MUTEX"), g_service_name, ms->ExeFileNameW);\r
4625                 return;\r
4626         }\r
4627 \r
4628         // サービス設定を更新する\r
4629         MsUpdateServiceConfig(g_service_name);\r
4630 \r
4631         if (ms->nt->StartServiceCtrlDispatcher(dispatch_table) == false)\r
4632         {\r
4633                 Alert("StartServiceCtrlDispatcher() Failed.", "MsServiceMode()");\r
4634                 return;\r
4635         }\r
4636 \r
4637         MsUpdateServiceConfig(g_service_name);\r
4638 \r
4639         FreeSingleInstance(inst);\r
4640 \r
4641         // サービス終了後は直ちにプロセスを終了する\r
4642         Wait(server_stopped_event, INFINITE);\r
4643         ReleaseEvent(server_stopped_event);\r
4644         WaitThread(service_stopper_thread, INFINITE);\r
4645         ReleaseThread(service_stopper_thread);\r
4646         server_stopped_event = NULL;\r
4647 \r
4648         _exit(0);\r
4649 }\r
4650 \r
4651 // テストモードとして起動\r
4652 void MsTestMode(char *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)\r
4653 {\r
4654         wchar_t *title_w = CopyStrToUni(title);\r
4655 \r
4656         MsTestModeW(title_w, start, stop);\r
4657         Free(title_w);\r
4658 }\r
4659 void MsTestModeW(wchar_t *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)\r
4660 {\r
4661         INSTANCE *inst;\r
4662         // 引数チェック\r
4663         if (title == NULL || start == NULL || stop == NULL)\r
4664         {\r
4665                 return;\r
4666         }\r
4667 \r
4668         is_usermode = true;\r
4669 \r
4670         inst = NewSingleInstance(NULL);\r
4671         if (inst == NULL)\r
4672         {\r
4673                 // すでに起動している\r
4674                 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_TEST_MUTEX"), ms->ExeFileNameW);\r
4675                 return;\r
4676         }\r
4677 \r
4678         // 起動\r
4679         start();\r
4680 \r
4681         // メッセージ表示\r
4682         MsgBoxEx(NULL, MB_ICONINFORMATION | MB_SYSTEMMODAL, _UU("SVC_TEST_MSG"), title);\r
4683 \r
4684         // 停止\r
4685         stop();\r
4686 \r
4687         FreeSingleInstance(inst);\r
4688 }\r
4689 \r
4690 // サービスマネージャを呼び出し中のプロセスのプロセス ID を書き込む\r
4691 void MsWriteCallingServiceManagerProcessId(char *svcname, UINT pid)\r
4692 {\r
4693         char tmp[MAX_PATH];\r
4694 \r
4695         Format(tmp, sizeof(tmp), SVC_CALLING_SM_PROCESS_ID_KEY, svcname);\r
4696 \r
4697         if (pid != 0)\r
4698         {\r
4699                 MsRegWriteInt(REG_LOCAL_MACHINE, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE, pid);\r
4700                 MsRegWriteInt(REG_CURRENT_USER, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE, pid);\r
4701         }\r
4702         else\r
4703         {\r
4704                 MsRegDeleteValue(REG_LOCAL_MACHINE, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE);\r
4705                 MsRegDeleteKey(REG_LOCAL_MACHINE, tmp);\r
4706 \r
4707                 MsRegDeleteValue(REG_CURRENT_USER, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE);\r
4708                 MsRegDeleteKey(REG_CURRENT_USER, tmp);\r
4709         }\r
4710 }\r
4711 \r
4712 // サービスマネージャを呼び出し中のプロセス ID を取得する\r
4713 UINT MsReadCallingServiceManagerProcessId(char *svcname, bool current_user)\r
4714 {\r
4715         char tmp[MAX_PATH];\r
4716         // 引数チェック\r
4717         if (svcname == NULL)\r
4718         {\r
4719                 return 0;\r
4720         }\r
4721 \r
4722         Format(tmp, sizeof(tmp), SVC_CALLING_SM_PROCESS_ID_KEY, svcname);\r
4723 \r
4724         return MsRegReadInt(current_user ? REG_CURRENT_USER : REG_LOCAL_MACHINE, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE);\r
4725 }\r
4726 \r
4727 // サービスメイン関数\r
4728 UINT MsService(char *name, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon)\r
4729 {\r
4730         UINT mode;\r
4731         UINT ret = 0;\r
4732         char *arg;\r
4733         wchar_t *arg_w;\r
4734         TOKEN_LIST *t = NULL;\r
4735         UNI_TOKEN_LIST *ut = NULL;\r
4736         char *service_name;\r
4737         wchar_t *service_title;\r
4738         wchar_t *service_description;\r
4739         wchar_t *service_title_uni;\r
4740         char tmp[MAX_SIZE];\r
4741         bool restoreReg = false;\r
4742         bool silent = false;\r
4743         // 引数チェック\r
4744         if (name == NULL || start == NULL || stop == NULL)\r
4745         {\r
4746                 return ret;\r
4747         }\r
4748 \r
4749         // Mayaqua の開始\r
4750         InitMayaqua(false, false, 0, NULL);\r
4751 \r
4752         // MS-IME の停止\r
4753         MsDisableIme();\r
4754 \r
4755         // サービスに関する情報を string table から取得\r
4756         Format(tmp, sizeof(tmp), SVC_NAME, name);\r
4757         service_name = _SS(tmp);\r
4758         Format(tmp, sizeof(tmp), SVC_TITLE, name);\r
4759         service_title = _UU(tmp);\r
4760         service_title_uni = _UU(tmp);\r
4761         Format(tmp, sizeof(tmp), SVC_DESCRIPT, name);\r
4762         service_description = _UU(tmp);\r
4763 \r
4764         if (StrLen(service_name) == 0 || UniStrLen(service_title) == 0)\r
4765         {\r
4766                 // サービス情報が見つからない\r
4767                 MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_NOT_FOUND"), name);\r
4768         }\r
4769         else\r
4770         {\r
4771                 wchar_t path[MAX_SIZE];\r
4772                 // 引数のチェック\r
4773                 mode = SVC_MODE_NONE;\r
4774 \r
4775                 t = GetCommandLineToken();\r
4776                 arg = NULL;\r
4777 \r
4778                 ut = GetCommandLineUniToken();\r
4779                 arg_w = NULL;\r
4780 \r
4781                 if (t->NumTokens >= 1)\r
4782                 {\r
4783                         arg = t->Token[0];\r
4784                 }\r
4785                 if(t->NumTokens >= 2)\r
4786                 {\r
4787                         if(StrCmpi(t->Token[1], SVC_ARG_SILENT) == 0)\r
4788                         {\r
4789                                 silent = true;\r
4790                         }\r
4791                 }\r
4792 \r
4793                 if (ut->NumTokens >= 1)\r
4794                 {\r
4795                         arg_w = ut->Token[0];\r
4796                 }\r
4797 \r
4798                 if (arg != NULL)\r
4799                 {\r
4800                         if (StrCmpi(arg, SVC_ARG_INSTALL) == 0)\r
4801                         {\r
4802                                 mode = SVC_MODE_INSTALL;\r
4803                         }\r
4804                         if (StrCmpi(arg, SVC_ARG_UNINSTALL) == 0)\r
4805                         {\r
4806                                 mode = SVC_MODE_UNINSTALL;\r
4807                         }\r
4808                         if (StrCmpi(arg, SVC_ARG_START) == 0)\r
4809                         {\r
4810                                 mode = SVC_MODE_START;\r
4811                         }\r
4812                         if (StrCmpi(arg, SVC_ARG_STOP) == 0)\r
4813                         {\r
4814                                 mode = SVC_MODE_STOP;\r
4815                         }\r
4816                         if (StrCmpi(arg, SVC_ARG_TEST) == 0)\r
4817                         {\r
4818                                 mode = SVC_MODE_TEST;\r
4819                         }\r
4820                         if (StrCmpi(arg, SVC_ARG_USERMODE) == 0)\r
4821                         {\r
4822                                 mode = SVC_MODE_USERMODE;\r
4823                         }\r
4824                         if (StrCmpi(arg, SVC_ARG_SETUP_INSTALL) == 0)\r
4825                         {\r
4826                                 mode = SVC_MODE_SETUP_INSTALL;\r
4827                         }\r
4828                         if (StrCmpi(arg, SVC_ARG_SETUP_UNINSTALL) == 0)\r
4829                         {\r
4830                                 mode = SVC_MODE_SETUP_UNINSTALL;\r
4831                         }\r
4832                         if (StrCmpi(arg, SVC_ARG_WIN9X_SERVICE) == 0)\r
4833                         {\r
4834                                 mode = SVC_MODE_WIN9X_SERVICE;\r
4835                         }\r
4836                         if (StrCmpi(arg, SVC_ARG_WIN9X_INSTALL) == 0)\r
4837                         {\r
4838                                 mode = SVC_MODE_WIN9X_INSTALL;\r
4839                         }\r
4840                         if (StrCmpi(arg, SVC_ARG_WIN9X_UNINSTALL) == 0)\r
4841                         {\r
4842                                 mode = SVC_MODE_WIN9X_UNINSTALL;\r
4843                         }\r
4844                         if (StrCmpi(arg, SVC_ARG_TCP) == 0)\r
4845                         {\r
4846                                 mode = SVC_MODE_TCP;\r
4847                         }\r
4848                         if (StrCmpi(arg, SVC_ARG_TCP_SETUP) == 0)\r
4849                         {\r
4850                                 mode = SVC_MODE_TCPSETUP;\r
4851                         }\r
4852                         if (StrCmpi(arg, SVC_ARG_TRAFFIC) == 0)\r
4853                         {\r
4854                                 mode = SVC_MODE_TRAFFIC;\r
4855                         }\r
4856                         if (StrCmpi(arg, SVC_ARG_UIHELP) == 0)\r
4857                         {\r
4858                                 mode = SVC_MODE_UIHELP;\r
4859                         }\r
4860                         if (StrCmpi(arg, SVC_ARG_USERMODE_SHOWTRAY) == 0)\r
4861                         {\r
4862                                 char tmp[MAX_SIZE];\r
4863                                 mode = SVC_MODE_USERMODE;\r
4864                                 Format(tmp, sizeof(tmp), SVC_HIDETRAY_REG_VALUE, service_title);\r
4865                                 MsRegDeleteValue(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, tmp);\r
4866                         }\r
4867                         if (StrCmpi(arg, SVC_ARG_USERMODE_HIDETRAY) == 0)\r
4868                         {\r
4869                                 char tmp[MAX_SIZE];\r
4870                                 mode = SVC_MODE_USERMODE;\r
4871                                 Format(tmp, sizeof(tmp), SVC_HIDETRAY_REG_VALUE, service_title);\r
4872                                 MsRegWriteInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, tmp, 1);\r
4873                         }\r
4874                         if (StrCmpi(arg, SVC_ARG_SERVICE) == 0)\r
4875                         {\r
4876                                 mode = SVC_MODE_SERVICE;\r
4877                         }\r
4878 \r
4879                         if (mode != SVC_MODE_NONE)\r
4880                         {\r
4881                                 // Network Config\r
4882                                 MsInitGlobalNetworkConfig();\r
4883                         }\r
4884                 }\r
4885 \r
4886                 // サービスとして実行する際のコマンドライン名を取得する\r
4887                 UniFormat(path, sizeof(path), SVC_RUN_COMMANDLINE, ms->ExeFileNameW);\r
4888 \r
4889                 if ((mode == SVC_MODE_INSTALL || mode == SVC_MODE_UNINSTALL || mode == SVC_MODE_START ||\r
4890                         mode == SVC_MODE_STOP || mode == SVC_MODE_SERVICE) &&\r
4891                         (ms->IsNt == false))\r
4892                 {\r
4893                         // Windows NT 以外で NT 系のコマンドを使用しようとした\r
4894                         MsgBox(NULL, MB_ICONSTOP, _UU("SVC_NT_ONLY"));\r
4895                 }\r
4896                 else if ((mode == SVC_MODE_INSTALL || mode == SVC_MODE_UNINSTALL || mode == SVC_MODE_START ||\r
4897                         mode == SVC_MODE_STOP || mode == SVC_MODE_SERVICE) &&\r
4898                         (ms->IsAdmin == false))\r
4899                 {\r
4900                         // Administrators 権限が無い\r
4901                         MsgBox(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_ADMIN"));\r
4902                 }\r
4903                 else\r
4904                 {\r
4905                         // モードごとに処理を行う\r
4906                         switch (mode)\r
4907                         {\r
4908                         case SVC_MODE_NONE:\r
4909                                 // 案内メッセージを表示して終了する\r
4910                                 if (arg_w != NULL && UniEndWith(arg_w, L".uvpn"))\r
4911                                 {\r
4912                                         if (MsgBox(NULL, MB_ICONQUESTION | MB_YESNO, _UU("CM_VPN_FILE_CLICKED")) == IDYES)\r
4913                                         {\r
4914                                                 wchar_t vpncmgr[MAX_PATH];\r
4915                                                 wchar_t filename[MAX_PATH];\r
4916 \r
4917                                                 UniFormat(filename, sizeof(filename), L"\"%s\"", arg_w);\r
4918 \r
4919                                                 if (Is64() == false)\r
4920                                                 {\r
4921                                                         UniFormat(vpncmgr, sizeof(vpncmgr), L"%s\\utvpncmgr.exe", MsGetExeDirNameW());\r
4922                                                 }\r
4923                                                 else\r
4924                                                 {\r
4925                                                         UniFormat(vpncmgr, sizeof(vpncmgr), L"%s\\utvpncmgr_x64.exe", MsGetExeDirNameW());\r
4926                                                 }\r
4927 \r
4928                                                 RunW(vpncmgr, filename, false, false);\r
4929                                         }\r
4930                                 }\r
4931                                 else\r
4932                                 {\r
4933                                         MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_HELP"),\r
4934                                                 service_title, service_name, service_title, service_title, service_name, service_title, service_name, service_title, service_name, service_title, service_name, service_title, service_title);\r
4935                                 }\r
4936                                 break;\r
4937 \r
4938                         case SVC_MODE_SETUP_INSTALL:\r
4939                                 // setup.exe インストール モード\r
4940                                 // 古いものをアンインストールする\r
4941                                 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());\r
4942                                 restoreReg = true;\r
4943 \r
4944                                 if (MsIsServiceInstalled(service_name))\r
4945                                 {\r
4946                                         if (MsIsServiceRunning(service_name))\r
4947                                         {\r
4948                                                 MsStopService(service_name);\r
4949                                         }\r
4950                                         MsUninstallService(service_name);\r
4951                                 }\r
4952                                 if (MsInstallServiceW(service_name, service_title, service_description, path) == false)\r
4953                                 {\r
4954                                         ret = 1;\r
4955                                 }\r
4956                                 MsStartService(service_name);\r
4957                                 MsWriteCallingServiceManagerProcessId(service_name, 0);\r
4958                                 break;\r
4959 \r
4960                         case SVC_MODE_SETUP_UNINSTALL:\r
4961                                 // setup.exe アンインストール モード\r
4962                                 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());\r
4963                                 restoreReg = true;\r
4964 \r
4965                                 if (MsIsServiceInstalled(service_name))\r
4966                                 {\r
4967                                         if (MsIsServiceRunning(service_name))\r
4968                                         {\r
4969                                                 MsStopService(service_name);\r
4970                                         }\r
4971                                         if (MsUninstallService(service_name) == false)\r
4972                                         {\r
4973                                                 ret = 1;\r
4974                                         }\r
4975                                 }\r
4976                                 break;\r
4977 \r
4978                         case SVC_MODE_INSTALL:\r
4979                                 // サービスのインストール\r
4980                                 // すでにインストールされているかどうか確認する\r
4981                                 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());\r
4982                                 restoreReg = true;\r
4983 \r
4984                                 if (MsIsServiceInstalled(service_name))\r
4985                                 {\r
4986                                         // すでにインストールされている\r
4987                                         // アンインストールするかどうか確認のメッセージを表示する\r
4988                                         if (silent == false)\r
4989                                         {\r
4990                                                 if (MsgBoxEx(NULL, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("SVC_ALREADY_INSTALLED"),\r
4991                                                         service_title, service_name) == IDNO)\r
4992                                                 {\r
4993                                                         // 処理をキャンセルする\r
4994                                                         break;\r
4995                                                 }\r
4996                                         }\r
4997                                         // 既存のサービスが動作しているか?\r
4998                                         if (MsIsServiceRunning(service_name))\r
4999                                         {\r
5000                                                 // 停止を試みる\r
5001                                                 if (MsStopService(service_name) == false)\r
5002                                                 {\r
5003                                                         // 停止に失敗した\r
5004                                                         MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_STOP_FAILED"),\r
5005                                                                 service_title, service_name);\r
5006                                                         break;\r
5007                                                 }\r
5008                                         }\r
5009                                         // アンインストールする\r
5010                                         if (MsUninstallService(service_name) == false)\r
5011                                         {\r
5012                                                 // アンインストールに失敗した\r
5013                                                 MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_UNINSTALL_FAILED"),\r
5014                                                         service_title, service_name);\r
5015                                                 break;\r
5016                                         }\r
5017                                 }\r
5018 \r
5019                                 // インストールを行う\r
5020                                 if (MsInstallServiceW(service_name, service_title, service_description, path) == false)\r
5021                                 {\r
5022                                         // インストールに失敗した\r
5023                                         MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_INSTALL_FAILED"),\r
5024                                                 service_title, service_name);\r
5025                                         break;\r
5026                                 }\r
5027 \r
5028                                 // サービスを開始する\r
5029                                 if (MsStartService(service_name) == false)\r
5030                                 {\r
5031                                         // 開始に失敗した\r
5032                                         MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_INSTALL_FAILED_2"),\r
5033                                                 service_title, service_name, path);\r
5034                                         break;\r
5035                                 }\r
5036 \r
5037                                 // すべて成功した\r
5038                                 if(silent == false)\r
5039                                 {\r
5040                                         MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_INSTALL_OK"),\r
5041                                                 service_title, service_name, path);\r
5042                                 }\r
5043                                 break;\r
5044 \r
5045                         case SVC_MODE_UNINSTALL:\r
5046                                 // サービスのアンインストール\r
5047                                 // すでにインストールされているかどうか確認する\r
5048                                 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());\r
5049                                 restoreReg = true;\r
5050 \r
5051                                 if (MsIsServiceInstalled(service_name) == false)\r
5052                                 {\r
5053                                         if(silent == false)\r
5054                                         {\r
5055                                                 MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_INSTALLED"),\r
5056                                                         service_title, service_name, path);\r
5057                                         }\r
5058                                         break;\r
5059                                 }\r
5060 \r
5061                                 // サービスが起動中の場合は停止する\r
5062                                 if (MsIsServiceRunning(service_name))\r
5063                                 {\r
5064                                         // サービスを停止する\r
5065                                         if (MsStopService(service_name) == false)\r
5066                                         {\r
5067                                                 // 停止に失敗した\r
5068                                                 MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_STOP_FAILED"),\r
5069                                                         service_title, service_name);\r
5070                                                 break;\r
5071                                         }\r
5072                                 }\r
5073 \r
5074                                 // サービスをアンインストールする\r
5075                                 if (MsUninstallService(service_name) == false)\r
5076                                 {\r
5077                                         MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_UNINSTALL_FAILED"),\r
5078                                                 service_title, service_name);\r
5079                                         break;\r
5080                                 }\r
5081 \r
5082                                 // すべて成功した\r
5083                                 if(silent == false)\r
5084                                 {\r
5085                                         MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_UNINSTALL_OK"),\r
5086                                                 service_title, service_name);\r
5087                                 }\r
5088                                 break;\r
5089 \r
5090                         case SVC_MODE_START:\r
5091                                 // サービスの開始\r
5092                                 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());\r
5093                                 restoreReg = true;\r
5094 \r
5095                                 if (MsIsServiceInstalled(service_name) == false)\r
5096                                 {\r
5097                                         // サービスはインストールされていない\r
5098                                         MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_INSTALLED"),\r
5099                                                 service_title, service_name);\r
5100                                         break;\r
5101                                 }\r
5102 \r
5103                                 // サービスが起動中かどうか確認する\r
5104                                 if (MsIsServiceRunning(service_name))\r
5105                                 {\r
5106                                         // サービスが起動中\r
5107                                         if(silent == false)\r
5108                                         {\r
5109                                                 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVR_ALREADY_START"),\r
5110                                                         service_title, service_name);\r
5111                                         }\r
5112                                         break;\r
5113                                 }\r
5114 \r
5115                                 // サービスを起動する\r
5116                                 if (MsStartService(service_name) == false)\r
5117                                 {\r
5118                                         // 開始に失敗した\r
5119                                         MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_START_FAILED"),\r
5120                                                 service_title, service_name);\r
5121                                         break;\r
5122                                 }\r
5123 \r
5124                                 // すべて成功した\r
5125                                 if(silent == false)\r
5126                                 {\r
5127                                         MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_START_OK"),\r
5128                                                 service_title, service_name);\r
5129                                 }\r
5130                                 break;\r
5131 \r
5132                         case SVC_MODE_STOP:\r
5133                                 // サービスの停止\r
5134                                 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());\r
5135                                 restoreReg = true;\r
5136 \r
5137                                 if (MsIsServiceInstalled(service_name) == false)\r
5138                                 {\r
5139                                         // サービスはインストールされていない\r
5140                                         if(silent == false)\r
5141                                         {\r
5142                                                 MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_INSTALLED"),\r
5143                                                         service_title, service_name);\r
5144                                         }\r
5145                                         break;\r
5146                                 }\r
5147 \r
5148                                 // サービスが起動中かどうか確認する\r
5149                                 if (MsIsServiceRunning(service_name) == false)\r
5150                                 {\r
5151                                         // サービスが停止中\r
5152                                         if(silent == false)\r
5153                                         {\r
5154                                                 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_ALREADY_STOP"),\r
5155                                                         service_title, service_name);\r
5156                                         }\r
5157                                         break;\r
5158                                 }\r
5159                                 // サービスを停止する\r
5160                                 if (MsStopService(service_name) == false)\r
5161                                 {\r
5162                                         // 停止に失敗した\r
5163                                         MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_STOP_FAILED"),\r
5164                                                 service_title, service_name);\r
5165                                         break;\r
5166                                 }\r
5167 \r
5168                                 // すべて成功した\r
5169                                 if(silent == false)\r
5170                                 {\r
5171                                         MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_STOP_OK"),\r
5172                                                 service_title, service_name);\r
5173                                 }\r
5174                                 break;\r
5175 \r
5176                         case SVC_MODE_TEST:\r
5177                                 // テストモード\r
5178                                 MsTestModeW(service_title, start, stop);\r
5179                                 break;\r
5180 \r
5181                         case SVC_MODE_WIN9X_SERVICE:\r
5182                                 // Win9x サービスモード\r
5183                                 // (タスクトレイのアイコンを無条件で非表示にする)\r
5184                                 if (MsIsNt())\r
5185                                 {\r
5186                                         // Windows 2000 以降では動作させない\r
5187                                         break;\r
5188                                 }\r
5189                                 service_for_9x_mode = true;\r
5190                         case SVC_MODE_USERMODE:\r
5191                                 // ユーザーモード\r
5192                                 MsUserModeW(service_title, start, stop, icon);\r
5193                                 break;\r
5194 \r
5195                         case SVC_MODE_WIN9X_INSTALL:\r
5196                                 // Win9x インストールモード\r
5197                                 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());\r
5198                                 restoreReg = true;\r
5199 \r
5200                                 if (MsIsNt() == false)\r
5201                                 {\r
5202                                         // レジストリキーの追加\r
5203                                         char cmdline[MAX_PATH];\r
5204                                         Format(cmdline, sizeof(cmdline), "\"%s\" %s",\r
5205                                                 MsGetExeFileName(), SVC_ARG_WIN9X_SERVICE);\r
5206                                         MsRegWriteStr(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_1,\r
5207                                                 name, cmdline);\r
5208                                         MsRegWriteStr(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_2,\r
5209                                                 name, cmdline);\r
5210 \r
5211                                         // 実行\r
5212                                         Run(MsGetExeFileName(), SVC_ARG_WIN9X_SERVICE, false, false);\r
5213                                 }\r
5214                                 break;\r
5215 \r
5216                         case SVC_MODE_WIN9X_UNINSTALL:\r
5217                                 // Win9x アンインストールモード\r
5218                                 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());\r
5219                                 restoreReg = true;\r
5220 \r
5221                                 if (MsIsNt() == false)\r
5222                                 {\r
5223                                         // レジストリキーの削除\r
5224                                         MsRegDeleteValue(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_1,\r
5225                                                 name);\r
5226                                         MsRegDeleteValue(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_2,\r
5227                                                 name);\r
5228 \r
5229                                         // 自分以外のすべてのプロセスを終了\r
5230                                         MsKillOtherInstance();\r
5231                                 }\r
5232                                 break;\r
5233 \r
5234                         case SVC_MODE_SERVICE:\r
5235                                 // サービスとして動作\r
5236                                 StrCpy(g_service_name, sizeof(g_service_name), service_name);\r
5237                                 MsServiceMode(start, stop);\r
5238                                 break;\r
5239 \r
5240                         case SVC_MODE_TCP:\r
5241                                 // TCP ユーティリティ\r
5242                                 InitCedar();\r
5243                                 InitWinUi(service_title_uni, NULL, 0);\r
5244                                 ShowTcpIpConfigUtil(NULL, true);\r
5245                                 FreeWinUi();\r
5246                                 FreeCedar();\r
5247                                 break;\r
5248 \r
5249                         case SVC_MODE_TCPSETUP:\r
5250                                 // TCP 最適化モード (インストーラから呼ばれる)\r
5251                                 InitCedar();\r
5252                                 InitWinUi(service_title_uni, NULL, 0);\r
5253                                 ShowTcpIpConfigUtil(NULL, false);\r
5254                                 FreeWinUi();\r
5255                                 FreeCedar();\r
5256                                 break;\r
5257 \r
5258                         case SVC_MODE_TRAFFIC:\r
5259                                 // 通信スループット測定ツール\r
5260                                 InitCedar();\r
5261                                 InitWinUi(service_title_uni, NULL, 0);\r
5262                                 CmTraffic(NULL);\r
5263                                 FreeWinUi();\r
5264                                 FreeCedar();\r
5265                                 break;\r
5266 \r
5267                         case SVC_MODE_UIHELP:\r
5268                                 // UI Helper の起動\r
5269                                 CnStart();\r
5270                                 break;\r
5271                         }\r
5272 \r
5273                 }\r
5274                 FreeToken(t);\r
5275                 UniFreeToken(ut);\r
5276 \r
5277                 if (restoreReg)\r
5278                 {\r
5279                         MsWriteCallingServiceManagerProcessId(service_name, 0);\r
5280                 }\r
5281         }\r
5282 \r
5283         FreeMayaqua();\r
5284 \r
5285         return 0;\r
5286 }\r
5287 \r
5288 // 指定したセッションのユーザー名を取得する\r
5289 wchar_t *MsGetSessionUserName(UINT session_id)\r
5290 {\r
5291         if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())\r
5292         {\r
5293                 wchar_t *ret;\r
5294                 wchar_t *name;\r
5295                 UINT size = 0;\r
5296                 if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id,\r
5297                         WTSUserName, (wchar_t *)&name, &size) == false)\r
5298                 {\r
5299                         return NULL;\r
5300                 }\r
5301 \r
5302                 if (name == NULL || UniStrLen(name) == 0)\r
5303                 {\r
5304                         ret = NULL;\r
5305                 }\r
5306                 else\r
5307                 {\r
5308                         ret = UniCopyStr(name);\r
5309                 }\r
5310 \r
5311                 ms->nt->WTSFreeMemory(name);\r
5312 \r
5313                 return ret;\r
5314         }\r
5315         return NULL;\r
5316 }\r
5317 \r
5318 // 現在のデスクトップが VNC で利用可能かどうか取得する\r
5319 bool MsIsCurrentDesktopAvailableForVnc()\r
5320 {\r
5321         if (MsIsNt() == false)\r
5322         {\r
5323                 return true;\r
5324         }\r
5325 \r
5326         if (MsIsCurrentTerminalSessionActive() == false)\r
5327         {\r
5328                 return false;\r
5329         }\r
5330 \r
5331         if (ms->nt->OpenDesktopA == NULL ||\r
5332                 ms->nt->CloseDesktop == NULL ||\r
5333                 ms->nt->SwitchDesktop == NULL)\r
5334         {\r
5335                 return true;\r
5336         }\r
5337         else\r
5338         {\r
5339                 HDESK hDesk = ms->nt->OpenDesktopA("default", 0, false, DESKTOP_SWITCHDESKTOP);\r
5340                 bool ret;\r
5341 \r
5342                 if (hDesk == NULL)\r
5343                 {\r
5344                         return false;\r
5345                 }\r
5346 \r
5347                 ret = ms->nt->SwitchDesktop(hDesk);\r
5348                 ms->nt->CloseDesktop(hDesk);\r
5349 \r
5350                 return ret;\r
5351         }\r
5352 }\r
5353 \r
5354 // 現在のターミナルセッションがアクティブかどうか取得する\r
5355 bool MsIsCurrentTerminalSessionActive()\r
5356 {\r
5357         return MsIsTerminalSessionActive(MsGetCurrentTerminalSessionId());\r
5358 }\r
5359 \r
5360 // 指定したターミナルセッションがアクティブかどうか取得する\r
5361 bool MsIsTerminalSessionActive(UINT session_id)\r
5362 {\r
5363         if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())\r
5364         {\r
5365                 UINT *status = NULL;\r
5366                 UINT size = sizeof(status);\r
5367                 bool active = true;\r
5368 \r
5369                 if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id,\r
5370                         WTSConnectState, (wchar_t *)&status, &size) == false)\r
5371                 {\r
5372                         return true;\r
5373                 }\r
5374 \r
5375                 switch (*status)\r
5376                 {\r
5377                 case WTSDisconnected:\r
5378                 case WTSShadow:\r
5379                 case WTSIdle:\r
5380                 case WTSDown:\r
5381                 case WTSReset:\r
5382                         active = false;\r
5383                         break;\r
5384                 }\r
5385 \r
5386                 ms->nt->WTSFreeMemory(status);\r
5387 \r
5388                 return active;\r
5389         }\r
5390 \r
5391         return true;\r
5392 }\r
5393 \r
5394 // 現在のターミナルセッション ID を取得する\r
5395 UINT MsGetCurrentTerminalSessionId()\r
5396 {\r
5397         if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())\r
5398         {\r
5399                 UINT ret;\r
5400                 UINT *session_id = NULL;\r
5401                 UINT size = sizeof(session_id);\r
5402                 if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION,\r
5403                         WTSSessionId, (wchar_t *)&session_id, &size) == false)\r
5404                 {\r
5405                         return 0;\r
5406                 }\r
5407 \r
5408                 ret = *session_id;\r
5409 \r
5410                 ms->nt->WTSFreeMemory(session_id);\r
5411 \r
5412                 return ret;\r
5413         }\r
5414 \r
5415         return 0;\r
5416 }\r
5417 \r
5418 // ターミナルサービスがインストールされていて複数セッションがログイン可能かどうか調べる\r
5419 bool MsIsTerminalServiceMultiUserInstalled()\r
5420 {\r
5421         OS_INFO *info = GetOsInfo();\r
5422         OSVERSIONINFOEX i;\r
5423         if (MsIsTerminalServiceInstalled() == false)\r
5424         {\r
5425                 return false;\r
5426         }\r
5427 \r
5428         if (OS_IS_SERVER(info->OsType) == false)\r
5429         {\r
5430                 return false;\r
5431         }\r
5432 \r
5433         Zero(&i, sizeof(i));\r
5434         i.dwOSVersionInfoSize = sizeof(i);\r
5435         if (GetVersionEx((OSVERSIONINFO *)&i) == false)\r
5436         {\r
5437                 return false;\r
5438         }\r
5439 \r
5440         if (i.wSuiteMask & VER_SUITE_SINGLEUSERTS)\r
5441         {\r
5442                 return false;\r
5443         }\r
5444 \r
5445         return true;\r
5446 }\r
5447 \r
5448 // ユーザー切り替えがインストールされているかどうか調べる\r
5449 bool MsIsUserSwitchingInstalled()\r
5450 {\r
5451         OS_INFO *info = GetOsInfo();\r
5452         OSVERSIONINFOEX i;\r
5453 \r
5454         if (OS_IS_WINDOWS_NT(info->OsType) == false)\r
5455         {\r
5456                 return false;\r
5457         }\r
5458 \r
5459         if (ms->nt->WTSDisconnectSession == NULL ||\r
5460                 ms->nt->WTSFreeMemory == NULL ||\r
5461                 ms->nt->WTSQuerySessionInformation == NULL)\r
5462         {\r
5463                 return false;\r
5464         }\r
5465 \r
5466         if (GET_KETA(info->OsType, 100) < 2)\r
5467         {\r
5468                 return false;\r
5469         }\r
5470 \r
5471         Zero(&i, sizeof(i));\r
5472         i.dwOSVersionInfoSize = sizeof(i);\r
5473         if (GetVersionEx((OSVERSIONINFO *)&i) == false)\r
5474         {\r
5475                 return false;\r
5476         }\r
5477 \r
5478         if (i.wSuiteMask & VER_SUITE_SINGLEUSERTS)\r
5479         {\r
5480                 return true;\r
5481         }\r
5482 \r
5483         return false;\r
5484 }\r
5485 \r
5486 // リモートデスクトップを有効にする\r
5487 bool MsEnableRemoteDesktop()\r
5488 {\r
5489         OS_INFO *info = GetOsInfo();\r
5490 \r
5491         if (MsIsRemoteDesktopAvailable() == false)\r
5492         {\r
5493                 return false;\r
5494         }\r
5495 \r
5496         if (MsIsRemoteDesktopEnabled())\r
5497         {\r
5498                 return true;\r
5499         }\r
5500 \r
5501         if (GET_KETA(info->OsType, 100) == 2)\r
5502         {\r
5503                 // Windows 2000\r
5504                 return false;\r
5505         }\r
5506 \r
5507         if (MsRegWriteInt(REG_LOCAL_MACHINE,\r
5508                 "SYSTEM\\CurrentControlSet\\Control\\Terminal Server",\r
5509                 "fDenyTSConnections", 0) == false)\r
5510         {\r
5511                 return false;\r
5512         }\r
5513 \r
5514         if (MsIsVista())\r
5515         {\r
5516                 if (MsRegWriteInt(REG_LOCAL_MACHINE,\r
5517                         "SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp",\r
5518                         "UserAuthentication", 0) == false)\r
5519                 {\r
5520                         return false;\r
5521                 }\r
5522         }\r
5523 \r
5524         return true;\r
5525 }\r
5526 \r
5527 // リモートデスクトップが有効かどうか調べる\r
5528 bool MsIsRemoteDesktopEnabled()\r
5529 {\r
5530         OS_INFO *info = GetOsInfo();\r
5531 \r
5532         if (MsIsRemoteDesktopAvailable() == false)\r
5533         {\r
5534                 return false;\r
5535         }\r
5536 \r
5537         if (GET_KETA(info->OsType, 100) == 2)\r
5538         {\r
5539                 // Windows 2000\r
5540                 return MsIsServiceRunning("TermService");\r
5541         }\r
5542         else\r
5543         {\r
5544                 // Windows XP 以降\r
5545                 bool b = MsRegReadInt(REG_LOCAL_MACHINE,\r
5546                         "SYSTEM\\CurrentControlSet\\Control\\Terminal Server",\r
5547                         "fDenyTSConnections");\r
5548 \r
5549                 if (MsIsVista() == false)\r
5550                 {\r
5551                         return b ? false : true;\r
5552                 }\r
5553                 else\r
5554                 {\r
5555                         if (b)\r
5556                         {\r
5557                                 return false;\r
5558                         }\r
5559                         else\r
5560                         {\r
5561                                 if (MsRegReadInt(REG_LOCAL_MACHINE,\r
5562                                         "SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp",\r
5563                                         "UserAuthentication"))\r
5564                                 {\r
5565                                         return false;\r
5566                                 }\r
5567                                 else\r
5568                                 {\r
5569                                         return true;\r
5570                                 }\r
5571                         }\r
5572                 }\r
5573         }\r
5574 }\r
5575 \r
5576 // レジストリ操作によってリモートデスクトップが利用可能になるかどうか調べる\r
5577 bool MsIsRemoteDesktopCanEnableByRegistory()\r
5578 {\r
5579         OS_INFO *info = GetOsInfo();\r
5580         if (MsIsRemoteDesktopAvailable() == false)\r
5581         {\r
5582                 return false;\r
5583         }\r
5584 \r
5585         if (GET_KETA(info->OsType, 100) == 2)\r
5586         {\r
5587                 // Windows 2000\r
5588                 return false;\r
5589         }\r
5590         else\r
5591         {\r
5592                 // それ以外\r
5593                 return true;\r
5594         }\r
5595 }\r
5596 \r
5597 // Windows 2000 かどうか調べる\r
5598 bool MsIsWin2000()\r
5599 {\r
5600         OS_INFO *info = GetOsInfo();\r
5601 \r
5602         if (OS_IS_WINDOWS_NT(info->OsType) == false)\r
5603         {\r
5604                 return false;\r
5605         }\r
5606 \r
5607         if (GET_KETA(info->OsType, 100) == 2)\r
5608         {\r
5609                 return true;\r
5610         }\r
5611 \r
5612         return false;\r
5613 }\r
5614 \r
5615 // Windows 2000 以降かどうか調べる\r
5616 bool MsIsWin2000OrGreater()\r
5617 {\r
5618         OS_INFO *info = GetOsInfo();\r
5619 \r
5620         if (OS_IS_WINDOWS_NT(info->OsType) == false)\r
5621         {\r
5622                 return false;\r
5623         }\r
5624 \r
5625         if (GET_KETA(info->OsType, 100) >= 2)\r
5626         {\r
5627                 return true;\r
5628         }\r
5629 \r
5630         return false;\r
5631 }\r
5632 \r
5633 // リモートデスクトップが利用可能かどうか調べる\r
5634 bool MsIsRemoteDesktopAvailable()\r
5635 {\r
5636         OS_INFO *info = GetOsInfo();\r
5637         if (MsIsTerminalServiceInstalled() == false)\r
5638         {\r
5639                 return false;\r
5640         }\r
5641 \r
5642         if (GET_KETA(info->OsType, 100) == 2)\r
5643         {\r
5644                 // Windows 2000\r
5645                 if (info->OsType == 2200)\r
5646                 {\r
5647                         // Windows 2000 Professional\r
5648                         return false;\r
5649                 }\r
5650                 else\r
5651                 {\r
5652                         // Windows 2000 サーバー系\r
5653                         return true;\r
5654                 }\r
5655         }\r
5656         else if (GET_KETA(info->OsType, 100) == 3)\r
5657         {\r
5658                 // Windows XP\r
5659                 if (info->OsType == OSTYPE_WINDOWS_XP_HOME)\r
5660                 {\r
5661                         // Home Edition\r
5662                         return false;\r
5663                 }\r
5664                 else\r
5665                 {\r
5666                         // Professional Edition\r
5667                         return true;\r
5668                 }\r
5669         }\r
5670         else if (GET_KETA(info->OsType, 100) == 4)\r
5671         {\r
5672                 // Windows Server 2003\r
5673                 return true;\r
5674         }\r
5675         else if (GET_KETA(info->OsType, 100) >= 5)\r
5676         {\r
5677                 // Windows Vista 以降\r
5678                 OSVERSIONINFOEX i;\r
5679 \r
5680                 Zero(&i, sizeof(i));\r
5681                 i.dwOSVersionInfoSize = sizeof(i);\r
5682                 if (GetVersionEx((OSVERSIONINFO *)&i) == false)\r
5683                 {\r
5684                         return false;\r
5685                 }\r
5686 \r
5687                 if (i.wSuiteMask & VER_SUITE_PERSONAL)\r
5688                 {\r
5689                         // Home 系\r
5690                         return false;\r
5691                 }\r
5692                 else\r
5693                 {\r
5694                         return true;\r
5695                 }\r
5696         }\r
5697 \r
5698         return false;\r
5699 }\r
5700 \r
5701 // ターミナルサービスがインストールされているかどうか調べる\r
5702 bool MsIsTerminalServiceInstalled()\r
5703 {\r
5704         OS_INFO *info = GetOsInfo();\r
5705         OSVERSIONINFOEX i;\r
5706 \r
5707         if (OS_IS_WINDOWS_NT(info->OsType) == false)\r
5708         {\r
5709                 return false;\r
5710         }\r
5711 \r
5712         if (ms->nt->WTSDisconnectSession == NULL ||\r
5713                 ms->nt->WTSFreeMemory == NULL ||\r
5714                 ms->nt->WTSQuerySessionInformation == NULL)\r
5715         {\r
5716                 return false;\r
5717         }\r
5718 \r
5719         if (GET_KETA(info->OsType, 100) < 2)\r
5720         {\r
5721                 return false;\r
5722         }\r
5723 \r
5724         Zero(&i, sizeof(i));\r
5725         i.dwOSVersionInfoSize = sizeof(i);\r
5726         if (GetVersionEx((OSVERSIONINFO *)&i) == false)\r
5727         {\r
5728                 return false;\r
5729         }\r
5730 \r
5731         if (i.wSuiteMask & VER_SUITE_TERMINAL || i.wSuiteMask & VER_SUITE_SINGLEUSERTS)\r
5732         {\r
5733                 return true;\r
5734         }\r
5735 \r
5736         return false;\r
5737 }\r
5738 \r
5739 // サービスを停止する\r
5740 bool MsStopService(char *name)\r
5741 {\r
5742         SC_HANDLE sc, service;\r
5743         bool ret = false;\r
5744         // 引数チェック\r
5745         if (name == NULL)\r
5746         {\r
5747                 return false;\r
5748         }\r
5749         if (ms->IsNt == false)\r
5750         {\r
5751                 return false;\r
5752         }\r
5753 \r
5754         sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
5755         if (sc == NULL)\r
5756         {\r
5757                 return false;\r
5758         }\r
5759 \r
5760         service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);\r
5761         if (service != NULL)\r
5762         {\r
5763                 SERVICE_STATUS st;\r
5764                 ret = ms->nt->ControlService(service, SERVICE_CONTROL_STOP, &st);\r
5765 \r
5766                 ms->nt->CloseServiceHandle(service);\r
5767         }\r
5768 \r
5769         if (ret)\r
5770         {\r
5771                 UINT64 end = Tick64() + 10000ULL;\r
5772                 while (Tick64() < end)\r
5773                 {\r
5774                         if (MsIsServiceRunning(name) == false)\r
5775                         {\r
5776                                 break;\r
5777                         }\r
5778 \r
5779                         SleepThread(250);\r
5780                 }\r
5781         }\r
5782 \r
5783         ms->nt->CloseServiceHandle(sc);\r
5784         return ret;\r
5785 }\r
5786 \r
5787 // サービスを起動する\r
5788 bool MsStartService(char *name)\r
5789 {\r
5790         return MsStartServiceEx(name, NULL);\r
5791 }\r
5792 bool MsStartServiceEx(char *name, UINT *error_code)\r
5793 {\r
5794         SC_HANDLE sc, service;\r
5795         bool ret = false;\r
5796         static UINT dummy = 0;\r
5797         // 引数チェック\r
5798         if (name == NULL)\r
5799         {\r
5800                 return false;\r
5801         }\r
5802         if (ms->IsNt == false)\r
5803         {\r
5804                 return false;\r
5805         }\r
5806         if (error_code == NULL)\r
5807         {\r
5808                 error_code = &dummy;\r
5809         }\r
5810 \r
5811         *error_code = 0;\r
5812 \r
5813         sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
5814         if (sc == NULL)\r
5815         {\r
5816                 *error_code = GetLastError();\r
5817                 return false;\r
5818         }\r
5819 \r
5820         service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);\r
5821         if (service != NULL)\r
5822         {\r
5823                 ret = ms->nt->StartService(service, 0, NULL);\r
5824 \r
5825                 ms->nt->CloseServiceHandle(service);\r
5826         }\r
5827         else\r
5828         {\r
5829                 *error_code = GetLastError();\r
5830         }\r
5831 \r
5832         if (ret)\r
5833         {\r
5834                 UINT64 end = Tick64() + 10000ULL;\r
5835                 while (Tick64() < end)\r
5836                 {\r
5837                         if (MsIsServiceRunning(name))\r
5838                         {\r
5839                                 break;\r
5840                         }\r
5841 \r
5842                         SleepThread(250);\r
5843                 }\r
5844         }\r
5845 \r
5846         ms->nt->CloseServiceHandle(sc);\r
5847         return ret;\r
5848 }\r
5849 \r
5850 // サービスが起動しているかどうか取得する\r
5851 bool MsIsServiceRunning(char *name)\r
5852 {\r
5853         SC_HANDLE sc, service;\r
5854         bool ret = false;\r
5855         // 引数チェック\r
5856         if (name == NULL || IsEmptyStr(name))\r
5857         {\r
5858                 return false;\r
5859         }\r
5860         if (ms->IsNt == false)\r
5861         {\r
5862                 return false;\r
5863         }\r
5864 \r
5865         sc = ms->nt->OpenSCManager(NULL, NULL, GENERIC_READ);\r
5866         if (sc == NULL)\r
5867         {\r
5868                 return false;\r
5869         }\r
5870 \r
5871         service = ms->nt->OpenService(sc, name, GENERIC_READ);\r
5872         if (service != NULL)\r
5873         {\r
5874                 SERVICE_STATUS st;\r
5875                 Zero(&st, sizeof(st));\r
5876                 if (ms->nt->QueryServiceStatus(service, &st))\r
5877                 {\r
5878                         switch (st.dwCurrentState)\r
5879                         {\r
5880                         case SERVICE_CONTINUE_PENDING:\r
5881                         case SERVICE_PAUSE_PENDING:\r
5882                         case SERVICE_PAUSED:\r
5883                         case SERVICE_RUNNING:\r
5884                         case SERVICE_START_PENDING:\r
5885                         case SERVICE_STOP_PENDING:\r
5886                                 ret = true;\r
5887                                 break;\r
5888                         }\r
5889                 }\r
5890 \r
5891                 ms->nt->CloseServiceHandle(service);\r
5892         }\r
5893 \r
5894         ms->nt->CloseServiceHandle(sc);\r
5895         return ret;\r
5896 }\r
5897 \r
5898 // サービスをアンインストールする\r
5899 bool MsUninstallService(char *name)\r
5900 {\r
5901         SC_HANDLE sc, service;\r
5902         bool ret = false;\r
5903         // 引数チェック\r
5904         if (name == NULL)\r
5905         {\r
5906                 return false;\r
5907         }\r
5908         if (ms->IsNt == false)\r
5909         {\r
5910                 return false;\r
5911         }\r
5912 \r
5913         MsStopService(name);\r
5914 \r
5915         sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
5916         if (sc == NULL)\r
5917         {\r
5918                 return false;\r
5919         }\r
5920 \r
5921         service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);\r
5922         if (service != NULL)\r
5923         {\r
5924                 if (ms->nt->DeleteService(service))\r
5925                 {\r
5926                         ret = true;\r
5927                 }\r
5928                 ms->nt->CloseServiceHandle(service);\r
5929         }\r
5930 \r
5931         ms->nt->CloseServiceHandle(sc);\r
5932 \r
5933         if (ret)\r
5934         {\r
5935                 SleepThread(2000);\r
5936         }\r
5937 \r
5938         return ret;\r
5939 }\r
5940 \r
5941 // サービス設定を更新する\r
5942 bool MsUpdateServiceConfig(char *name)\r
5943 {\r
5944         SC_HANDLE sc, service;\r
5945         // 引数チェック\r
5946         if (name == NULL)\r
5947         {\r
5948                 return false;\r
5949         }\r
5950 \r
5951         // Windows 起動直後かどうか (デッドロック防止)\r
5952         if (timeGetTime() <= (60 * 30 * 1000))\r
5953         {\r
5954                 if (MsRegReadInt(REG_LOCAL_MACHINE, "Software\\SoftEther Corporation\\Update Service Config", name) != 0)\r
5955                 {\r
5956                         return false;\r
5957                 }\r
5958         }\r
5959 \r
5960         sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
5961         if (sc == NULL)\r
5962         {\r
5963                 return false;\r
5964         }\r
5965 \r
5966         service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);\r
5967         if (service != NULL)\r
5968         {\r
5969                 if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)\r
5970                 {\r
5971                         SERVICE_FAILURE_ACTIONS action;\r
5972                         SC_ACTION *e;\r
5973                         Zero(&action, sizeof(action));\r
5974                         e = ZeroMalloc(sizeof(SC_ACTION) * 3);\r
5975                         e[0].Delay = 10000; e[0].Type = SC_ACTION_RESTART;\r
5976                         e[1].Delay = 10000; e[1].Type = SC_ACTION_RESTART;\r
5977                         e[2].Delay = 10000; e[2].Type = SC_ACTION_RESTART;\r
5978                         action.cActions = 3;\r
5979                         action.lpsaActions = e;\r
5980                         action.dwResetPeriod = 1 * 60 * 60 * 24;\r
5981                         ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_FAILURE_ACTIONS, &action);\r
5982 \r
5983                         MsRegWriteInt(REG_LOCAL_MACHINE, "Software\\SoftEther Corporation\\Update Service Config", name, 1);\r
5984                 }\r
5985                 ms->nt->CloseServiceHandle(service);\r
5986         }\r
5987 \r
5988         ms->nt->CloseServiceHandle(sc);\r
5989 \r
5990         return true;\r
5991 }\r
5992 \r
5993 // サービスをインストールする\r
5994 bool MsInstallService(char *name, char *title, wchar_t *description, char *path)\r
5995 {\r
5996         wchar_t title_w[MAX_PATH];\r
5997         wchar_t path_w[MAX_PATH];\r
5998         // 引数チェック\r
5999         if (name == NULL || title == NULL || path == NULL)\r
6000         {\r
6001                 return false;\r
6002         }\r
6003 \r
6004         StrToUni(title_w, sizeof(title_w), title);\r
6005         StrToUni(path_w, sizeof(path_w), path);\r
6006 \r
6007         return MsInstallServiceW(name, title_w, description, path_w);\r
6008 }\r
6009 bool MsInstallServiceW(char *name, wchar_t *title, wchar_t *description, wchar_t *path)\r
6010 {\r
6011         return MsInstallServiceExW(name, title, description, path, NULL);\r
6012 }\r
6013 bool MsInstallServiceExW(char *name, wchar_t *title, wchar_t *description, wchar_t *path, UINT *error_code)\r
6014 {\r
6015         SC_HANDLE sc, service;\r
6016         bool ret = false;\r
6017         wchar_t name_w[MAX_SIZE];\r
6018         static UINT temp_int = 0;\r
6019         // 引数チェック\r
6020         if (name == NULL || title == NULL || path == NULL)\r
6021         {\r
6022                 return false;\r
6023         }\r
6024         if (ms->IsNt == false)\r
6025         {\r
6026                 return false;\r
6027         }\r
6028         if (error_code == NULL)\r
6029         {\r
6030                 error_code = &temp_int;\r
6031         }\r
6032 \r
6033         *error_code = 0;\r
6034 \r
6035         StrToUni(name_w, sizeof(name_w), name);\r
6036 \r
6037         sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
6038         if (sc == NULL)\r
6039         {\r
6040                 *error_code = GetLastError();\r
6041                 return false;\r
6042         }\r
6043 \r
6044         service = ms->nt->CreateServiceW(sc, name_w, title, SERVICE_ALL_ACCESS,\r
6045                 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS , SERVICE_AUTO_START,\r
6046                 SERVICE_ERROR_NORMAL, path, NULL, NULL, NULL, NULL, NULL);\r
6047 \r
6048         if (service != NULL)\r
6049         {\r
6050                 ret = true;\r
6051 \r
6052                 if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)\r
6053                 {\r
6054                         SERVICE_DESCRIPTIONW d;\r
6055                         SERVICE_FAILURE_ACTIONS action;\r
6056                         SC_ACTION *e;\r
6057                         Zero(&d, sizeof(d));\r
6058                         d.lpDescription = description;\r
6059                         ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &d);\r
6060                         Zero(&action, sizeof(action));\r
6061                         e = ZeroMalloc(sizeof(SC_ACTION) * 3);\r
6062                         e[0].Delay = 10000; e[0].Type = SC_ACTION_RESTART;\r
6063                         e[1].Delay = 10000; e[1].Type = SC_ACTION_RESTART;\r
6064                         e[2].Delay = 10000; e[2].Type = SC_ACTION_RESTART;\r
6065                         action.cActions = 3;\r
6066                         action.lpsaActions = e;\r
6067                         action.dwResetPeriod = 1 * 60 * 60 * 24;\r
6068                         ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_FAILURE_ACTIONS, &action);\r
6069 \r
6070                         Free(e);\r
6071                 }\r
6072 \r
6073                 ms->nt->CloseServiceHandle(service);\r
6074         }\r
6075         else\r
6076         {\r
6077                 *error_code = GetLastError();\r
6078         }\r
6079 \r
6080         ms->nt->CloseServiceHandle(sc);\r
6081 \r
6082         if (ret)\r
6083         {\r
6084                 SleepThread(2000);\r
6085         }\r
6086 \r
6087         return ret;\r
6088 }\r
6089 \r
6090 // 指定したサービスがインストールされているかどうか調べる\r
6091 bool MsIsServiceInstalled(char *name)\r
6092 {\r
6093         SC_HANDLE sc;\r
6094         SC_HANDLE service;\r
6095         bool ret = false;\r
6096         // 引数チェック\r
6097         if (name == NULL)\r
6098         {\r
6099                 return false;\r
6100         }\r
6101         if (ms->IsNt == false)\r
6102         {\r
6103                 return false;\r
6104         }\r
6105 \r
6106         sc = ms->nt->OpenSCManager(NULL, NULL, GENERIC_READ);\r
6107         if (sc == NULL)\r
6108         {\r
6109                 return false;\r
6110         }\r
6111 \r
6112         service = ms->nt->OpenService(sc, name, GENERIC_READ);\r
6113         if (service != NULL)\r
6114         {\r
6115                 ret = true;\r
6116         }\r
6117 \r
6118         ms->nt->CloseServiceHandle(service);\r
6119         ms->nt->CloseServiceHandle(sc);\r
6120 \r
6121         return ret;\r
6122 }\r
6123 \r
6124 // プロセスの強制終了\r
6125 void MsTerminateProcess()\r
6126 {\r
6127         TerminateProcess(GetCurrentProcess(), 0);\r
6128         _exit(0);\r
6129 }\r
6130 \r
6131 // プロセス ID の取得\r
6132 UINT MsGetProcessId()\r
6133 {\r
6134         return GetCurrentProcessId();\r
6135 }\r
6136 \r
6137 // MS 構造体の取得\r
6138 MS *MsGetMs()\r
6139 {\r
6140         return ms;\r
6141 }\r
6142 \r
6143 // スレッドの優先順位を最低にする\r
6144 void MsSetThreadPriorityIdle()\r
6145 {\r
6146         SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);\r
6147 }\r
6148 \r
6149 // スレッドの優先順位を上げる\r
6150 void MsSetThreadPriorityHigh()\r
6151 {\r
6152         SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);\r
6153 }\r
6154 \r
6155 // スレッドの優先順位を下げる\r
6156 void MsSetThreadPriorityLow()\r
6157 {\r
6158         SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);\r
6159 }\r
6160 \r
6161 // スレッドの優先順位を最高にする\r
6162 void MsSetThreadPriorityRealtime()\r
6163 {\r
6164         SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);\r
6165         SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);\r
6166         SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);\r
6167 }\r
6168 \r
6169 // スレッドの優先順位を戻す\r
6170 void MsRestoreThreadPriority()\r
6171 {\r
6172         SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);\r
6173 }\r
6174 \r
6175 // TCP 設定アプリケーションを表示するべきかどうかチェックする\r
6176 bool MsIsShouldShowTcpConfigApp()\r
6177 {\r
6178         MS_TCP tcp1, tcp2;\r
6179         if (MsIsTcpConfigSupported() == false)\r
6180         {\r
6181                 return false;\r
6182         }\r
6183 \r
6184         MsGetTcpConfig(&tcp1);\r
6185         if (MsLoadTcpConfigReg(&tcp2) == false)\r
6186         {\r
6187                 return true;\r
6188         }\r
6189 \r
6190         if (Cmp(&tcp1, &tcp2, sizeof(MS_TCP) != 0))\r
6191         {\r
6192                 return true;\r
6193         }\r
6194 \r
6195         return false;\r
6196 }\r
6197 \r
6198 // レジストリの一時設定内容データを Windows の TCP パラメータに適用する\r
6199 void MsApplyTcpConfig()\r
6200 {\r
6201         if (MsIsTcpConfigSupported())\r
6202         {\r
6203                 MS_TCP tcp;\r
6204 \r
6205                 if (MsLoadTcpConfigReg(&tcp))\r
6206                 {\r
6207                         MsSetTcpConfig(&tcp);\r
6208                 }\r
6209         }\r
6210 }\r
6211 \r
6212 // 現在の状態で TCP の動的構成がサポートされているかどうかチェックする\r
6213 bool MsIsTcpConfigSupported()\r
6214 {\r
6215         if (MsIsNt() && MsIsAdmin())\r
6216         {\r
6217                 UINT type = GetOsInfo()->OsType;\r
6218 \r
6219                 if (GET_KETA(type, 100) >= 2)\r
6220                 {\r
6221                         return true;\r
6222                 }\r
6223         }\r
6224 \r
6225         return false;\r
6226 }\r
6227 \r
6228 // TCP 設定をレジストリ設定から読み込む\r
6229 bool MsLoadTcpConfigReg(MS_TCP *tcp)\r
6230 {\r
6231         // 引数チェック\r
6232         if (tcp == NULL)\r
6233         {\r
6234                 return false;\r
6235         }\r
6236 \r
6237         if (MsIsNt())\r
6238         {\r
6239                 Zero(tcp, sizeof(MS_TCP));\r
6240 \r
6241                 if (MsRegIsValueEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "RecvWindowSize", true) == false ||\r
6242                         MsRegIsValueEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "SendWindowSize", true) == false)\r
6243                 {\r
6244                         return false;\r
6245                 }\r
6246 \r
6247                 tcp->RecvWindowSize = MsRegReadIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "RecvWindowSize", true);\r
6248                 tcp->SendWindowSize = MsRegReadIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "SendWindowSize", true);\r
6249 \r
6250                 return true;\r
6251         }\r
6252         else\r
6253         {\r
6254                 return false;\r
6255         }\r
6256 }\r
6257 \r
6258 // TCP 設定をレジストリから削除する\r
6259 void MsDeleteTcpConfigReg()\r
6260 {\r
6261         if (MsIsNt() && MsIsAdmin())\r
6262         {\r
6263                 MsRegDeleteKeyEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, true);\r
6264         }\r
6265 }\r
6266 \r
6267 // TCP 設定をレジストリ設定に書き込む\r
6268 void MsSaveTcpConfigReg(MS_TCP *tcp)\r
6269 {\r
6270         // 引数チェック\r
6271         if (tcp == NULL)\r
6272         {\r
6273                 return;\r
6274         }\r
6275 \r
6276         if (MsIsNt() && MsIsAdmin())\r
6277         {\r
6278                 MsRegWriteIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "RecvWindowSize", tcp->RecvWindowSize, true);\r
6279                 MsRegWriteIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "SendWindowSize", tcp->SendWindowSize, true);\r
6280         }\r
6281 }\r
6282 \r
6283 // 現在の TCP 設定を取得する\r
6284 void MsGetTcpConfig(MS_TCP *tcp)\r
6285 {\r
6286         // 引数チェック\r
6287         if (tcp == NULL)\r
6288         {\r
6289                 return;\r
6290         }\r
6291 \r
6292         Zero(tcp, sizeof(MS_TCP));\r
6293 \r
6294         if (MsIsNt())\r
6295         {\r
6296                 // ネットワーク設定初期化\r
6297                 MsInitGlobalNetworkConfig();\r
6298 \r
6299                 // GlobalMaxTcpWindowSize または TcpWindowSize の値が存在すれば読み込む\r
6300                 tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "TcpWindowSize"));\r
6301                 tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "GlobalMaxTcpWindowSize"));\r
6302                 tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "DefaultReceiveWindow"));\r
6303 \r
6304                 // DefaultSendWindow の値が存在すれば読み込む\r
6305                 tcp->SendWindowSize = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "DefaultSendWindow");\r
6306         }\r
6307 }\r
6308 \r
6309 // TCP 設定を書き込む\r
6310 void MsSetTcpConfig(MS_TCP *tcp)\r
6311 {\r
6312         // 引数チェック\r
6313         if (tcp == NULL)\r
6314         {\r
6315                 return;\r
6316         }\r
6317 \r
6318         if (MsIsNt() && MsIsAdmin())\r
6319         {\r
6320                 bool window_scaling = false;\r
6321                 UINT tcp1323opts;\r
6322 \r
6323                 if (tcp->RecvWindowSize >= 65536 || tcp->SendWindowSize >= 65536)\r
6324                 {\r
6325                         window_scaling = true;\r
6326                 }\r
6327 \r
6328                 // Tcp1323Opts の設定\r
6329                 tcp1323opts = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "Tcp1323Opts");\r
6330                 if (window_scaling)\r
6331                 {\r
6332                         if (tcp1323opts == 0)\r
6333                         {\r
6334                                 tcp1323opts = 1;\r
6335                         }\r
6336                         if (tcp1323opts == 2)\r
6337                         {\r
6338                                 tcp1323opts = 3;\r
6339                         }\r
6340                 }\r
6341                 else\r
6342                 {\r
6343                         if (tcp1323opts == 1)\r
6344                         {\r
6345                                 tcp1323opts = 0;\r
6346                         }\r
6347                         if (tcp1323opts == 3)\r
6348                         {\r
6349                                 tcp1323opts = 2;\r
6350                         }\r
6351                 }\r
6352                 MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "Tcp1323Opts", tcp1323opts);\r
6353 \r
6354                 // 受信ウインドウの設定\r
6355                 if (tcp->RecvWindowSize == 0)\r
6356                 {\r
6357                         MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",\r
6358                                 "DefaultReceiveWindow");\r
6359                         MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
6360                                 "TcpWindowSize");\r
6361                         MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
6362                                 "GlobalMaxTcpWindowSize");\r
6363                 }\r
6364                 else\r
6365                 {\r
6366                         MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",\r
6367                                 "DefaultReceiveWindow", tcp->RecvWindowSize);\r
6368                         MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
6369                                 "TcpWindowSize", tcp->RecvWindowSize);\r
6370                         MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
6371                                 "GlobalMaxTcpWindowSize", tcp->RecvWindowSize);\r
6372                 }\r
6373 \r
6374                 // 送信ウインドウの設定\r
6375                 if (tcp->SendWindowSize == 0)\r
6376                 {\r
6377                         MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",\r
6378                                 "DefaultSendWindow");\r
6379                 }\r
6380                 else\r
6381                 {\r
6382                         MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",\r
6383                                 "DefaultSendWindow", tcp->SendWindowSize);\r
6384                 }\r
6385         }\r
6386 }\r
6387 \r
6388 // グローバルなネットワーク設定を初期化する\r
6389 void MsInitGlobalNetworkConfig()\r
6390 {\r
6391         if (MsIsNt())\r
6392         {\r
6393                 UINT current_window_size;\r
6394 \r
6395                 if (MsRegReadInt(REG_LOCAL_MACHINE,\r
6396                         "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
6397                         "packetix_no_optimize") == 0)\r
6398 \r
6399                 {\r
6400                         // TCP コネクション数を最大にする\r
6401                         MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
6402                                 "TcpNumConnections", TCP_MAX_NUM_CONNECTIONS);\r
6403 \r
6404                         // タスク オフロードを無効化する\r
6405                         MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
6406                                 "DisableTaskOffload", 1);\r
6407                 }\r
6408 \r
6409                 current_window_size = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "TcpWindowSize");\r
6410 \r
6411                 if (current_window_size == 65535 || current_window_size == 5980160 ||\r
6412                         current_window_size == 16777216 || current_window_size == 16777214)\r
6413                 {\r
6414                         // 古いバージョンの VPN が書き込んでしまった変な値を削除する\r
6415                         MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",\r
6416                                 "DefaultReceiveWindow");\r
6417                         MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",\r
6418                                 "DefaultSendWindow");\r
6419                         MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
6420                                 "Tcp1323Opts");\r
6421                         MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
6422                                 "TcpWindowSize");\r
6423                         MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
6424                                 "GlobalMaxTcpWindowSize");\r
6425 \r
6426                         // vpn_no_change = true にする\r
6427                         MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "vpn_no_change", 1);\r
6428                         MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "vpn_no_change", 1);\r
6429                 }\r
6430         }\r
6431         else\r
6432         {\r
6433                 if (MsRegReadInt(REG_LOCAL_MACHINE,\r
6434                         "System\\CurrentControlSet\\Services\\VxD\\MSTCP",\r
6435                         "packetix_no_optimize") == 0)\r
6436                 {\r
6437                         // DeadGWDetect を無効にする\r
6438                         MsRegWriteStr(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\MSTCP",\r
6439                                 "DeadGWDetect", "0");\r
6440                 }\r
6441         }\r
6442 \r
6443         MsApplyTcpConfig();\r
6444 }\r
6445 \r
6446 // 仮想 LAN カードをアップグレードする\r
6447 bool MsUpgradeVLan(char *tag_name, char *connection_tag_name, char *instance_name)\r
6448 {\r
6449         wchar_t infpath[MAX_PATH];\r
6450         char hwid[MAX_PATH];\r
6451         wchar_t hwid_w[MAX_PATH];\r
6452         bool ret = false;\r
6453         bool need_reboot;\r
6454         bool before_status;\r
6455         UCHAR old_mac_address[6];\r
6456         char *s;\r
6457         NO_WARNING *nw;\r
6458         char sen_sys[MAX_PATH];\r
6459         // 引数チェック\r
6460         if (instance_name == NULL || tag_name == NULL || connection_tag_name == NULL)\r
6461         {\r
6462                 return false;\r
6463         }\r
6464 \r
6465         if (MsIsNt() == false)\r
6466         {\r
6467                 // Windows 9x ではアップグレードできない\r
6468                 return false;\r
6469         }\r
6470 \r
6471         Zero(hwid, sizeof(hwid));\r
6472         Format(hwid, sizeof(hwid), DRIVER_DEVICE_ID_TAG, instance_name);\r
6473         StrToUni(hwid_w, sizeof(hwid_w), hwid);\r
6474 \r
6475         // 指定された名前の仮想 LAN カードがすでに登録されているかどうかを調べる\r
6476         if (MsIsVLanExists(tag_name, instance_name) == false)\r
6477         {\r
6478                 // 登録されていない\r
6479                 return false;\r
6480         }\r
6481 \r
6482         // 現在使用している .sys ファイル名を取得する\r
6483         if (MsGetSenDeiverFilename(sen_sys, sizeof(sen_sys), instance_name) == false)\r
6484         {\r
6485                 // 不明なので新しいファイル名を作成する\r
6486                 if (MsMakeNewSenDriverFilename(sen_sys, sizeof(sen_sys)) == false)\r
6487                 {\r
6488                         // 失敗\r
6489                         return false;\r
6490                 }\r
6491         }\r
6492 \r
6493         // 現在の動作状況を取得する\r
6494         before_status = MsIsVLanEnabled(instance_name);\r
6495 \r
6496         // 以前の MAC アドレスを取得する\r
6497         s = MsGetMacAddress(tag_name, instance_name);\r
6498         if (s == NULL)\r
6499         {\r
6500                 Zero(old_mac_address, 6);\r
6501         }\r
6502         else\r
6503         {\r
6504                 BUF *b;\r
6505                 b = StrToBin(s);\r
6506                 Free(s);\r
6507 \r
6508                 if (b->Size == 6)\r
6509                 {\r
6510                         Copy(old_mac_address, b->Buf, b->Size);\r
6511                 }\r
6512                 else\r
6513                 {\r
6514                         Zero(old_mac_address, 6);\r
6515                 }\r
6516 \r
6517                 FreeBuf(b);\r
6518         }\r
6519 \r
6520         // インストール開始\r
6521         if (MsStartDriverInstall(instance_name, IsZero(old_mac_address, 6) ? NULL : old_mac_address, sen_sys) == false)\r
6522         {\r
6523                 return false;\r
6524         }\r
6525         MsGetDriverPath(instance_name, NULL, NULL, infpath, NULL, sen_sys);\r
6526 \r
6527         nw = NULL;\r
6528 \r
6529         //if (MsIsVista() == false)\r
6530         {\r
6531                 nw = MsInitNoWarning();\r
6532         }\r
6533 \r
6534         // インストールを行う\r
6535         if (ms->nt->UpdateDriverForPlugAndPlayDevicesW(\r
6536                 NULL, hwid_w, infpath, 1, &need_reboot))\r
6537         {\r
6538                 ret = true;\r
6539         }\r
6540         MsFreeNoWarning(nw);\r
6541 \r
6542         // インストール完了\r
6543         MsFinishDriverInstall(instance_name, sen_sys);\r
6544 \r
6545         MsInitNetworkConfig(tag_name, instance_name, connection_tag_name);\r
6546 \r
6547         // 動作を復元する\r
6548         if (before_status)\r
6549         {\r
6550                 MsEnableVLan(instance_name);\r
6551         }\r
6552         else\r
6553         {\r
6554                 MsDisableVLan(instance_name);\r
6555         }\r
6556 \r
6557         return ret;\r
6558 }\r
6559 \r
6560 // Windows 9x 用テスト\r
6561 void MsWin9xTest()\r
6562 {\r
6563 }\r
6564 \r
6565 // 仮想 LAN カードの CompatibleIDs を更新する\r
6566 void MsUpdateCompatibleIDs(char *instance_name)\r
6567 {\r
6568         TOKEN_LIST *t;\r
6569         char id[MAX_SIZE];\r
6570         char device_title[MAX_SIZE];\r
6571         char device_title_old[MAX_SIZE];\r
6572         // 引数チェック\r
6573         if (instance_name == NULL)\r
6574         {\r
6575                 return;\r
6576         }\r
6577 \r
6578         Format(id, sizeof(id), DRIVER_DEVICE_ID_TAG, instance_name);\r
6579         Format(device_title, sizeof(device_title), VLAN_ADAPTER_NAME_TAG, instance_name);\r
6580         Format(device_title_old, sizeof(device_title_old), "---dummy-string-ut--", instance_name);\r
6581 \r
6582         t = MsRegEnumKey(REG_LOCAL_MACHINE, "Enum\\Root\\Net");\r
6583         if (t != NULL)\r
6584         {\r
6585                 UINT i;\r
6586                 for (i = 0;i < t->NumTokens;i++)\r
6587                 {\r
6588                         char keyname[MAX_PATH];\r
6589                         char *str;\r
6590                         char *title;\r
6591 \r
6592                         Format(keyname, sizeof(keyname), "Enum\\Root\\Net\\%s", t->Token[i]);\r
6593 \r
6594                         title = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "DeviceDesc");\r
6595 \r
6596                         if (title != NULL)\r
6597                         {\r
6598                                 if (StrCmpi(title, device_title) == 0 || StrCmpi(title, device_title_old) == 0)\r
6599                                 {\r
6600                                         Format(keyname, sizeof(keyname), "Enum\\Root\\Net\\%s",t->Token[i]);\r
6601                                         str = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "CompatibleIDs");\r
6602                                         if (str != NULL)\r
6603                                         {\r
6604                                                 Free(str);\r
6605                                         }\r
6606                                         else\r
6607                                         {\r
6608                                                 MsRegWriteStr(REG_LOCAL_MACHINE, keyname, "CompatibleIDs", id);\r
6609                                         }\r
6610                                 }\r
6611                                 Free(title);\r
6612                         }\r
6613                 }\r
6614 \r
6615                 FreeToken(t);\r
6616         }\r
6617 \r
6618         MsRegWriteStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", "SourcePath",\r
6619                 ms->System32Dir);\r
6620 }\r
6621 \r
6622 // 仮想 LAN カードをインストールする (Win9x 用)\r
6623 bool MsInstallVLan9x(char *instance_name)\r
6624 {\r
6625         char sysdir[MAX_PATH];\r
6626         char infdir[MAX_PATH];\r
6627         char otherdir[MAX_PATH];\r
6628         char syspath[MAX_PATH];\r
6629         char syspath2[MAX_PATH];\r
6630         char infpath[MAX_PATH];\r
6631         char vpn16[MAX_PATH];\r
6632         char infpath_src[MAX_PATH];\r
6633         char syspath_src[MAX_PATH];\r
6634         char sen_sys[MAX_PATH];\r
6635         // 引数チェック\r
6636         if (instance_name == NULL)\r
6637         {\r
6638                 return false;\r
6639         }\r
6640 \r
6641         StrCpy(sysdir, sizeof(sysdir), MsGetSystem32Dir());\r
6642         Format(infdir, sizeof(infdir), "%s\\inf", MsGetWindowsDir());\r
6643         Format(otherdir, sizeof(otherdir), "%s\\other", infdir);\r
6644         Format(syspath, sizeof(syspath), "%s\\Sen_%s.sys", sysdir, instance_name);\r
6645         Format(syspath2, sizeof(syspath2), "%s\\Sen_%s.sys", infdir, instance_name);\r
6646         Format(infpath, sizeof(infpath), "%s\\Sen_%s.inf", infdir, instance_name);\r
6647         Format(vpn16, sizeof(vpn16), "%s\\vpn16.exe", MsGetMyTempDir());\r
6648 \r
6649         MakeDir(otherdir);\r
6650 \r
6651         Format(sen_sys, sizeof(sen_sys), DRIVER_INSTALL_SYS_NAME_TAG, instance_name);\r
6652 \r
6653         // vpn16.exe のコピー\r
6654         FileCopy("|vpn16.exe", vpn16);\r
6655 \r
6656         // インストール開始\r
6657         if (MsStartDriverInstall(instance_name, NULL, sen_sys) == false)\r
6658         {\r
6659                 return false;\r
6660         }\r
6661         MsGetDriverPathA(instance_name, NULL, NULL, infpath_src, syspath_src, sen_sys);\r
6662 \r
6663         // inf ファイルのコピー\r
6664         FileCopy(infpath_src, infpath);\r
6665 \r
6666         // sys ファイルのコピー\r
6667         FileCopy(syspath_src, syspath);\r
6668 \r
6669         // デバイスドライバのインストール\r
6670         if (Run(vpn16, instance_name, false, true) == false)\r
6671         {\r
6672                 return false;\r
6673         }\r
6674 \r
6675         // CompatibleIDs の更新\r
6676         MsUpdateCompatibleIDs(instance_name);\r
6677 \r
6678         return true;\r
6679 }\r
6680 \r
6681 // 子ウインドウ列挙プロシージャ\r
6682 bool CALLBACK MsEnumChildWindowProc(HWND hWnd, LPARAM lParam)\r
6683 {\r
6684         LIST *o = (LIST *)lParam;\r
6685 \r
6686         if (o != NULL)\r
6687         {\r
6688                 MsEnumChildWindows(o, hWnd);\r
6689         }\r
6690 \r
6691         return true;\r
6692 }\r
6693 \r
6694 // 指定したウインドウとその子ウインドウをすべて列挙する\r
6695 LIST *MsEnumChildWindows(LIST *o, HWND hWnd)\r
6696 {\r
6697         // 引数チェック\r
6698         if (hWnd == NULL)\r
6699         {\r
6700                 return NULL;\r
6701         }\r
6702 \r
6703         if (o == NULL)\r
6704         {\r
6705                 o = NewListFast(NULL);\r
6706         }\r
6707 \r
6708         MsAddWindowToList(o, hWnd);\r
6709 \r
6710         EnumChildWindows(hWnd, MsEnumChildWindowProc, (LPARAM)o);\r
6711 \r
6712         return o;\r
6713 }\r
6714 \r
6715 // ウインドウをリストに追加する\r
6716 void MsAddWindowToList(LIST *o, HWND hWnd)\r
6717 {\r
6718         // 引数チェック\r
6719         if (o == NULL || hWnd == NULL)\r
6720         {\r
6721                 return;\r
6722         }\r
6723 \r
6724         if (IsInList(o, hWnd) == false)\r
6725         {\r
6726                 Add(o, hWnd);\r
6727         }\r
6728 }\r
6729 \r
6730 // スレッドの所有するウインドウの列挙\r
6731 bool CALLBACK MsEnumThreadWindowProc(HWND hWnd, LPARAM lParam)\r
6732 {\r
6733         LIST *o = (LIST *)lParam;\r
6734 \r
6735         if (o == NULL)\r
6736         {\r
6737                 return false;\r
6738         }\r
6739 \r
6740         MsEnumChildWindows(o, hWnd);\r
6741 \r
6742         return true;\r
6743 }\r
6744 \r
6745 // ウインドウ列挙プロシージャ\r
6746 BOOL CALLBACK EnumTopWindowProc(HWND hWnd, LPARAM lParam)\r
6747 {\r
6748         LIST *o = (LIST *)lParam;\r
6749         HWND hParent;\r
6750         char c1[MAX_SIZE], c2[MAX_SIZE];\r
6751         // 引数チェック\r
6752         if (hWnd == NULL || o == NULL)\r
6753         {\r
6754                 return TRUE;\r
6755         }\r
6756 \r
6757         Zero(c1, sizeof(c1));\r
6758         Zero(c2, sizeof(c2));\r
6759 \r
6760         hParent = GetParent(hWnd);\r
6761 \r
6762         GetClassName(hWnd, c1, sizeof(c1));\r
6763 \r
6764         if (hParent != NULL)\r
6765         {\r
6766                 GetClassName(hParent, c2, sizeof(c2));\r
6767         }\r
6768 \r
6769         if (StrCmpi(c1, "SysIPAddress32") != 0 && (IsEmptyStr(c2) || StrCmpi(c2, "SysIPAddress32") != 0))\r
6770         {\r
6771                 AddWindow(o, hWnd);\r
6772         }\r
6773 \r
6774         return TRUE;\r
6775 }\r
6776 \r
6777 // 子ウインドウ列挙プロシージャ\r
6778 BOOL CALLBACK EnumChildWindowProc(HWND hWnd, LPARAM lParam)\r
6779 {\r
6780         ENUM_CHILD_WINDOW_PARAM *p = (ENUM_CHILD_WINDOW_PARAM *)lParam;\r
6781         LIST *o;\r
6782         HWND hParent;\r
6783         char c1[MAX_SIZE], c2[MAX_SIZE];\r
6784         // 引数チェック\r
6785         if (hWnd == NULL || p == NULL)\r
6786         {\r
6787                 return TRUE;\r
6788         }\r
6789 \r
6790         o = p->o;\r
6791 \r
6792         Zero(c1, sizeof(c1));\r
6793         Zero(c2, sizeof(c2));\r
6794 \r
6795         hParent = GetParent(hWnd);\r
6796 \r
6797         GetClassName(hWnd, c1, sizeof(c1));\r
6798 \r
6799         if (hParent != NULL)\r
6800         {\r
6801                 GetClassName(hParent, c2, sizeof(c2));\r
6802         }\r
6803 \r
6804         if (p->include_ipcontrol || (StrCmpi(c1, "SysIPAddress32") != 0 && (IsEmptyStr(c2) || StrCmpi(c2, "SysIPAddress32") != 0)))\r
6805         {\r
6806                 AddWindow(o, hWnd);\r
6807 \r
6808                 if (p->no_recursion == false)\r
6809                 {\r
6810                         EnumChildWindows(hWnd, EnumChildWindowProc, (LPARAM)p);\r
6811                 }\r
6812         }\r
6813 \r
6814         return TRUE;\r
6815 }\r
6816 LIST *EnumAllWindow()\r
6817 {\r
6818         return EnumAllWindowEx(false, false);\r
6819 }\r
6820 LIST *EnumAllWindowEx(bool no_recursion, bool include_ipcontrol)\r
6821 {\r
6822         ENUM_CHILD_WINDOW_PARAM p;\r
6823         LIST *o = NewWindowList();\r
6824 \r
6825         Zero(&p, sizeof(p));\r
6826         p.o = o;\r
6827         p.no_recursion = no_recursion;\r
6828         p.include_ipcontrol = include_ipcontrol;\r
6829 \r
6830         EnumWindows(EnumChildWindowProc, (LPARAM)&p);\r
6831 \r
6832         return o;\r
6833 }\r
6834 LIST *EnumAllTopWindow()\r
6835 {\r
6836         LIST *o = NewWindowList();\r
6837 \r
6838         EnumWindows(EnumTopWindowProc, (LPARAM)o);\r
6839 \r
6840         return o;\r
6841 }\r
6842 \r
6843 // 特定のウインドウの中にあるすべての子ウインドウを列挙する\r
6844 LIST *EnumAllChildWindow(HWND hWnd)\r
6845 {\r
6846         return EnumAllChildWindowEx(hWnd, false, false, false);\r
6847 }\r
6848 LIST *EnumAllChildWindowEx(HWND hWnd, bool no_recursion, bool include_ipcontrol, bool no_self)\r
6849 {\r
6850         ENUM_CHILD_WINDOW_PARAM p;\r
6851         LIST *o = NewWindowList();\r
6852 \r
6853         Zero(&p, sizeof(p));\r
6854         p.include_ipcontrol = include_ipcontrol;\r
6855         p.no_recursion = no_recursion;\r
6856         p.o = o;\r
6857 \r
6858         if (no_self == false)\r
6859         {\r
6860                 AddWindow(o, hWnd);\r
6861         }\r
6862 \r
6863         EnumChildWindows(hWnd, EnumChildWindowProc, (LPARAM)&p);\r
6864 \r
6865         return o;\r
6866 }\r
6867 \r
6868 // ウインドウリストの解放\r
6869 void FreeWindowList(LIST *o)\r
6870 {\r
6871         UINT i;\r
6872         // 引数チェック\r
6873         if (o == NULL)\r
6874         {\r
6875                 return;\r
6876         }\r
6877 \r
6878         for (i = 0;i < LIST_NUM(o);i++)\r
6879         {\r
6880                 HWND *e = LIST_DATA(o, i);\r
6881 \r
6882                 Free(e);\r
6883         }\r
6884 \r
6885         ReleaseList(o);\r
6886 }\r
6887 \r
6888 // ウインドウリストにウインドウを追加\r
6889 void AddWindow(LIST *o, HWND hWnd)\r
6890 {\r
6891         HWND t, *e;\r
6892         // 引数チェック\r
6893         if (o == NULL || hWnd == NULL)\r
6894         {\r
6895                 return;\r
6896         }\r
6897 \r
6898         t = hWnd;\r
6899 \r
6900         if (Search(o, &t) != NULL)\r
6901         {\r
6902                 return;\r
6903         }\r
6904 \r
6905         e = ZeroMalloc(sizeof(HWND));\r
6906         *e = hWnd;\r
6907 \r
6908         Insert(o, e);\r
6909 }\r
6910 \r
6911 // ウインドウリストの比較\r
6912 int CmpWindowList(void *p1, void *p2)\r
6913 {\r
6914         HWND *h1, *h2;\r
6915         if (p1 == NULL || p2 == NULL)\r
6916         {\r
6917                 return 0;\r
6918         }\r
6919         h1 = *(HWND **)p1;\r
6920         h2 = *(HWND **)p2;\r
6921         if (h1 == NULL || h2 == NULL)\r
6922         {\r
6923                 return 0;\r
6924         }\r
6925 \r
6926         return Cmp(h1, h2, sizeof(HWND));\r
6927 }\r
6928 \r
6929 // 新しいウインドウリストの作成\r
6930 LIST *NewWindowList()\r
6931 {\r
6932         return NewListFast(CmpWindowList);\r
6933 }\r
6934 \r
6935 // Windows Vista かどうか判別\r
6936 bool MsIsVista()\r
6937 {\r
6938         OS_INFO *info = GetOsInfo();\r
6939 \r
6940         if (info == NULL)\r
6941         {\r
6942                 return false;\r
6943         }\r
6944 \r
6945         if (OS_IS_WINDOWS_NT(info->OsType))\r
6946         {\r
6947                 if (GET_KETA(info->OsType, 100) >= 5)\r
6948                 {\r
6949                         return true;\r
6950                 }\r
6951         }\r
6952 \r
6953         return false;\r
6954 }\r
6955 \r
6956 // ウインドウの所有者のプロセスパスを取得する\r
6957 bool MsGetWindowOwnerProcessExeName(char *path, UINT size, HWND hWnd)\r
6958 {\r
6959         DWORD procId = 0;\r
6960         // 引数チェック\r
6961         if (path == NULL || hWnd == NULL)\r
6962         {\r
6963                 return false;\r
6964         }\r
6965 \r
6966         GetWindowThreadProcessId(hWnd, &procId);\r
6967         if (procId == 0)\r
6968         {\r
6969                 return false;\r
6970         }\r
6971 \r
6972         if (MsGetProcessExeName(path, size, procId) == false)\r
6973         {\r
6974                 return false;\r
6975         }\r
6976 \r
6977         return true;\r
6978 }\r
6979 bool MsGetWindowOwnerProcessExeNameW(wchar_t *path, UINT size, HWND hWnd)\r
6980 {\r
6981         DWORD procId = 0;\r
6982         // 引数チェック\r
6983         if (path == NULL || hWnd == NULL)\r
6984         {\r
6985                 return false;\r
6986         }\r
6987 \r
6988         GetWindowThreadProcessId(hWnd, &procId);\r
6989         if (procId == 0)\r
6990         {\r
6991                 return false;\r
6992         }\r
6993 \r
6994         if (MsGetProcessExeNameW(path, size, procId) == false)\r
6995         {\r
6996                 return false;\r
6997         }\r
6998 \r
6999         return true;\r
7000 }\r
7001 \r
7002 // プロセス ID からプロセスパスを取得する\r
7003 bool MsGetProcessExeName(char *path, UINT size, UINT id)\r
7004 {\r
7005         LIST *o;\r
7006         MS_PROCESS *proc;\r
7007         bool ret = false;\r
7008         // 引数チェック\r
7009         if (path == NULL)\r
7010         {\r
7011                 return false;\r
7012         }\r
7013 \r
7014         o = MsGetProcessList();\r
7015         proc = MsSearchProcessById(o, id);\r
7016 \r
7017         if (proc != NULL)\r
7018         {\r
7019                 ret = true;\r
7020                 StrCpy(path, size, proc->ExeFilename);\r
7021         }\r
7022 \r
7023         MsFreeProcessList(o);\r
7024 \r
7025         return ret;\r
7026 }\r
7027 bool MsGetProcessExeNameW(wchar_t *path, UINT size, UINT id)\r
7028 {\r
7029         LIST *o;\r
7030         MS_PROCESS *proc;\r
7031         bool ret = false;\r
7032         // 引数チェック\r
7033         if (path == NULL)\r
7034         {\r
7035                 return false;\r
7036         }\r
7037 \r
7038         o = MsGetProcessList();\r
7039         proc = MsSearchProcessById(o, id);\r
7040 \r
7041         if (proc != NULL)\r
7042         {\r
7043                 ret = true;\r
7044                 UniStrCpy(path, size, proc->ExeFilenameW);\r
7045         }\r
7046 \r
7047         MsFreeProcessList(o);\r
7048 \r
7049         return ret;\r
7050 }\r
7051 \r
7052 // 警告ダイアログを閉じる\r
7053 bool MsCloseWarningWindow(UINT thread_id)\r
7054 {\r
7055         UINT i;\r
7056         LIST *o;\r
7057         bool ret = false;\r
7058 \r
7059         if (MsIsVista() == false)\r
7060         {\r
7061                 o = NewListFast(NULL);\r
7062                 EnumThreadWindows(thread_id, MsEnumThreadWindowProc, (LPARAM)o);\r
7063         }\r
7064         else\r
7065         {\r
7066                 o = EnumAllTopWindow();\r
7067         }\r
7068 \r
7069         for (i = 0;i < LIST_NUM(o);i++)\r
7070         {\r
7071                 HWND hWnd;\r
7072                 \r
7073                 if (MsIsVista() == false)\r
7074                 {\r
7075                         hWnd = LIST_DATA(o, i);\r
7076                 }\r
7077                 else\r
7078                 {\r
7079                         hWnd = *((HWND *)LIST_DATA(o, i));\r
7080                 }\r
7081 \r
7082                 if (hWnd != NULL)\r
7083                 {\r
7084                         OS_INFO *info = GetOsInfo();\r
7085 \r
7086                         if (MsIsNt())\r
7087                         {\r
7088                                 // このウインドウがドライバの警告画面かどうかを取得する\r
7089                                 if (MsIsVista() == false)\r
7090                                 {\r
7091                                         // Windows Vista 以外\r
7092                                         HWND hStatic, hOk, hCancel, hDetail;\r
7093 \r
7094                                         hStatic = GetDlgItem(hWnd, 0x14C1);\r
7095                                         hOk = GetDlgItem(hWnd, 0x14B7);\r
7096                                         hCancel = GetDlgItem(hWnd, 0x14BA);\r
7097                                         hDetail = GetDlgItem(hWnd, 0x14B9);\r
7098 \r
7099                                         if ((hStatic != NULL || hDetail != NULL) && hOk != NULL && hCancel != NULL)\r
7100                                         {\r
7101                                                 char tmp[MAX_SIZE];\r
7102                                                 bool b = false;\r
7103 \r
7104                                                 if (GetClassName(hStatic, tmp, sizeof(tmp)) != 0)\r
7105                                                 {\r
7106                                                         if (StrCmpi(tmp, "static") == 0)\r
7107                                                         {\r
7108                                                                 b = true;\r
7109                                                         }\r
7110                                                 }\r
7111 \r
7112                                                 if (GetClassName(hDetail, tmp, sizeof(tmp)) != 0)\r
7113                                                 {\r
7114                                                         if (StrCmpi(tmp, "button") == 0)\r
7115                                                         {\r
7116                                                                 b = true;\r
7117                                                         }\r
7118                                                 }\r
7119 \r
7120                                                 if (b)\r
7121                                                 {\r
7122                                                         if (GetClassName(hOk, tmp, sizeof(tmp)) != 0)\r
7123                                                         {\r
7124                                                                 if (StrCmpi(tmp, "button") == 0)\r
7125                                                                 {\r
7126                                                                         if (GetClassName(hCancel, tmp, sizeof(tmp)) != 0)\r
7127                                                                         {\r
7128                                                                                 if (StrCmpi(tmp, "button") == 0)\r
7129                                                                                 {\r
7130                                                                                         // 発見したので OK ボタンを押す\r
7131                                                                                         PostMessage(hWnd, WM_COMMAND, 0x14B7, 0);\r
7132 \r
7133                                                                                         ret = true;\r
7134                                                                                 }\r
7135                                                                         }\r
7136                                                                 }\r
7137                                                         }\r
7138                                                 }\r
7139                                         }\r
7140                                 }\r
7141                                 else\r
7142                                 {\r
7143                                         // Windows Vista\r
7144                                         char exe[MAX_PATH];\r
7145 \r
7146                                         if (MsGetWindowOwnerProcessExeName(exe, sizeof(exe), hWnd))\r
7147                                         {\r
7148                                                 if (EndWith(exe, "rundll32.exe"))\r
7149                                                 {\r
7150                                                         LIST *o;\r
7151                                                         HWND h;\r
7152                                                         UINT i;\r
7153 \r
7154                                                         o = EnumAllChildWindow(hWnd);\r
7155 \r
7156                                                         if (o != NULL)\r
7157                                                         {\r
7158                                                                 for (i = 0;i < LIST_NUM(o);i++)\r
7159                                                                 {\r
7160                                                                         char tmp[MAX_SIZE];\r
7161 \r
7162                                                                         h = *((HWND *)LIST_DATA(o, i));\r
7163 \r
7164                                                                         Zero(tmp, sizeof(tmp));\r
7165                                                                         GetClassNameA(h, tmp, sizeof(tmp));\r
7166 \r
7167                                                                         if (StrCmpi(tmp, "DirectUIHWND") == 0)\r
7168                                                                         {\r
7169                                                                                 LIST *o = EnumAllChildWindow(h);\r
7170 \r
7171                                                                                 if (o != NULL)\r
7172                                                                                 {\r
7173                                                                                         UINT j;\r
7174                                                                                         UINT numDirectUIHWND = 0;\r
7175                                                                                         UINT numButton = 0;\r
7176                                                                                         HWND hButton1 = NULL;\r
7177                                                                                         HWND hButton2 = NULL;\r
7178 \r
7179                                                                                         for (j = 0;j < LIST_NUM(o);j++)\r
7180                                                                                         {\r
7181                                                                                                 HWND hh;\r
7182                                                                                                 char tmp[MAX_SIZE];\r
7183 \r
7184                                                                                                 hh = *((HWND *)LIST_DATA(o, j));\r
7185 \r
7186                                                                                                 Zero(tmp, sizeof(tmp));\r
7187                                                                                                 GetClassNameA(hh, tmp, sizeof(tmp));\r
7188 \r
7189                                                                                                 if (StrCmpi(tmp, "DirectUIHWND") == 0)\r
7190                                                                                                 {\r
7191                                                                                                         numDirectUIHWND++;\r
7192                                                                                                 }\r
7193 \r
7194                                                                                                 if (StrCmpi(tmp, "button") == 0)\r
7195                                                                                                 {\r
7196                                                                                                         numButton++;\r
7197                                                                                                         if (hButton1 == NULL)\r
7198                                                                                                         {\r
7199                                                                                                                 hButton1 = hh;\r
7200                                                                                                         }\r
7201                                                                                                         else\r
7202                                                                                                         {\r
7203                                                                                                                 hButton2 = hh;\r
7204                                                                                                         }\r
7205                                                                                                 }\r
7206                                                                                         }\r
7207 \r
7208                                                                                         if (numDirectUIHWND == 1 && numButton == 2)\r
7209                                                                                         {\r
7210                                                                                                 if (hButton1 != NULL && hButton2 != NULL)\r
7211                                                                                                 {\r
7212                                                                                                         HWND hButton;\r
7213                                                                                                         HWND hParent;\r
7214                                                                                                         RECT r1, r2;\r
7215 \r
7216                                                                                                         GetWindowRect(hButton1, &r1);\r
7217                                                                                                         GetWindowRect(hButton2, &r2);\r
7218 \r
7219                                                                                                         hButton = hButton1;\r
7220 \r
7221                                                                                                         if (r1.top < r2.top)\r
7222                                                                                                         {\r
7223                                                                                                                 hButton = hButton2;\r
7224                                                                                                         }\r
7225 \r
7226                                                                                                         hParent = GetParent(hButton);\r
7227 \r
7228                                                                                                         // 発見したので OK ボタンを押す\r
7229                                                                                                         PostMessage(hParent, WM_COMMAND, 1, 0);\r
7230 \r
7231                                                                                                         ret = true;\r
7232                                                                                                 }\r
7233                                                                                         }\r
7234 \r
7235                                                                                         FreeWindowList(o);\r
7236                                                                                 }\r
7237                                                                         }\r
7238                                                                 }\r
7239 \r
7240                                                                 FreeWindowList(o);\r
7241                                                         }\r
7242                                                 }\r
7243                                         }\r
7244                                 }\r
7245                         }\r
7246                 }\r
7247         }\r
7248 \r
7249         if (MsIsVista() == false)\r
7250         {\r
7251                 ReleaseList(o);\r
7252         }\r
7253         else\r
7254         {\r
7255                 FreeWindowList(o);\r
7256         }\r
7257 \r
7258         return ret;\r
7259 }\r
7260 \r
7261 // 警告を出さないようにするためのスレッド\r
7262 void MsNoWarningThreadProc(THREAD *thread, void *param)\r
7263 {\r
7264         NO_WARNING *nw;\r
7265         UINT interval;\r
7266         UINT i;\r
7267         bool found0 = false;\r
7268         // 引数チェック\r
7269         if (thread == NULL)\r
7270         {\r
7271                 return;\r
7272         }\r
7273 \r
7274         nw = (NO_WARNING *)param;\r
7275 \r
7276         nw->NoWarningThread = thread;\r
7277         AddRef(thread->ref);\r
7278 \r
7279         NoticeThreadInit(thread);\r
7280 \r
7281         interval = 50;\r
7282 \r
7283         if (MsIsVista())\r
7284         {\r
7285                 interval = 1000;\r
7286         }\r
7287 \r
7288         i = 0;\r
7289 \r
7290         while (nw->Halt == false)\r
7291         {\r
7292                 bool found;\r
7293 \r
7294                 // 警告ダイアログを閉じる\r
7295                 found = MsCloseWarningWindow(nw->ThreadId);\r
7296                 if (i == 0)\r
7297                 {\r
7298                         found0 = found;\r
7299                 }\r
7300                 else\r
7301                 {\r
7302                         if (found0 == false && found)\r
7303                         {\r
7304                                 break;\r
7305                         }\r
7306                 }\r
7307                 i++;\r
7308 \r
7309                 // 親スレッドが指示するまでループする\r
7310                 Wait(nw->HaltEvent, interval);\r
7311         }\r
7312 }\r
7313 \r
7314 // 警告音を消す処理の初期化\r
7315 char *MsNoWarningSoundInit()\r
7316 {\r
7317         char *ret = MsRegReadStr(REG_CURRENT_USER, "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current", "");\r
7318 \r
7319         if (IsEmptyStr(ret))\r
7320         {\r
7321                 Free(ret);\r
7322                 ret = NULL;\r
7323         }\r
7324         else\r
7325         {\r
7326                 MsRegWriteStr(REG_CURRENT_USER,\r
7327                         "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",\r
7328                         "", "");\r
7329         }\r
7330 \r
7331         return ret;\r
7332 }\r
7333 \r
7334 // 警告音を消す処理の解放\r
7335 void MsNoWarningSoundFree(char *s)\r
7336 {\r
7337         // 引数チェック\r
7338         if (s == NULL)\r
7339         {\r
7340                 return;\r
7341         }\r
7342 \r
7343         MsRegWriteStrExpand(REG_CURRENT_USER,\r
7344                 "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",\r
7345                 "", s);\r
7346 \r
7347         Free(s);\r
7348 }\r
7349 \r
7350 // 警告を出さないようにする処理の開始\r
7351 NO_WARNING *MsInitNoWarning()\r
7352 {\r
7353         wchar_t *tmp;\r
7354         THREAD *thread;\r
7355         NO_WARNING *nw = ZeroMalloc(sizeof(NO_WARNING));\r
7356 \r
7357         // 現在のサウンドファイル名を取得する\r
7358         tmp = MsRegReadStrW(REG_CURRENT_USER, "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current", "");\r
7359         if (UniIsEmptyStr(tmp) == false)\r
7360         {\r
7361                 nw->SoundFileName = CopyUniStr(tmp);\r
7362 \r
7363                 MsRegWriteStrW(REG_CURRENT_USER,\r
7364                         "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",\r
7365                         "", L"");\r
7366         }\r
7367 \r
7368         Free(tmp);\r
7369 \r
7370         nw->ThreadId = GetCurrentThreadId();\r
7371         nw->HaltEvent = NewEvent();\r
7372 \r
7373         thread = NewThread(MsNoWarningThreadProc, nw);\r
7374         WaitThreadInit(thread);\r
7375 \r
7376         ReleaseThread(thread);\r
7377 \r
7378         return nw;\r
7379 }\r
7380 \r
7381 // 警告を出さないようにする処理の終了\r
7382 void MsFreeNoWarning(NO_WARNING *nw)\r
7383 {\r
7384         // 引数チェック\r
7385         if (nw == NULL)\r
7386         {\r
7387                 return;\r
7388         }\r
7389 \r
7390         nw->Halt = true;\r
7391         Set(nw->HaltEvent);\r
7392 \r
7393         WaitThread(nw->NoWarningThread, INFINITE);\r
7394         ReleaseThread(nw->NoWarningThread);\r
7395 \r
7396         ReleaseEvent(nw->HaltEvent);\r
7397 \r
7398         if (nw->SoundFileName != NULL)\r
7399         {\r
7400                 MsRegWriteStrExpandW(REG_CURRENT_USER,\r
7401                         "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",\r
7402                         "", nw->SoundFileName);\r
7403 \r
7404                 Free(nw->SoundFileName);\r
7405         }\r
7406 \r
7407         Free(nw);\r
7408 }\r
7409 \r
7410 // 仮想 LAN カードをインストールする\r
7411 bool MsInstallVLan(char *tag_name, char *connection_tag_name, char *instance_name)\r
7412 {\r
7413         wchar_t infpath[MAX_PATH];\r
7414         wchar_t inf_class_name[MAX_PATH];\r
7415         GUID inf_class_guid;\r
7416         HDEVINFO device_info;\r
7417         SP_DEVINFO_DATA device_info_data;\r
7418         char hwid[MAX_PATH];\r
7419         wchar_t hwid_w[MAX_PATH];\r
7420         bool ret = false;\r
7421         bool need_reboot;\r
7422         char sen_sys[MAX_PATH];\r
7423         UINT i;\r
7424         // 引数チェック\r
7425         if (instance_name == NULL || tag_name == NULL || connection_tag_name == NULL)\r
7426         {\r
7427                 return false;\r
7428         }\r
7429 \r
7430         if (MsIsNt() == false)\r
7431         {\r
7432                 // Windows 9x 用\r
7433                 return MsInstallVLan9x(instance_name);\r
7434         }\r
7435 \r
7436         Zero(hwid, sizeof(hwid));\r
7437         Format(hwid, sizeof(hwid), DRIVER_DEVICE_ID_TAG, instance_name);\r
7438         StrToUni(hwid_w, sizeof(hwid_w), hwid);\r
7439 \r
7440         // 指定された名前の仮想 LAN カードがすでに登録されているかどうかを調べる\r
7441         if (MsIsVLanExists(tag_name, instance_name))\r
7442         {\r
7443                 // すでに登録されている\r
7444                 return false;\r
7445         }\r
7446 \r
7447         // インストール先 .sys ファイル名の決定\r
7448         if (MsMakeNewSenDriverFilename(sen_sys, sizeof(sen_sys)) == false)\r
7449         {\r
7450                 return false;\r
7451         }\r
7452 \r
7453         // インストール開始\r
7454         if (MsStartDriverInstall(instance_name, NULL, sen_sys) == false)\r
7455         {\r
7456                 return false;\r
7457         }\r
7458         MsGetDriverPath(instance_name, NULL, NULL, infpath, NULL, sen_sys);\r
7459 \r
7460         // inf ファイルのクラス GUID を取得する\r
7461         if (SetupDiGetINFClassW(infpath, &inf_class_guid, inf_class_name, sizeof(inf_class_name), NULL))\r
7462         {\r
7463                 // デバイス情報セットを取得する\r
7464                 device_info = SetupDiCreateDeviceInfoList(&inf_class_guid, NULL);\r
7465                 if (device_info != INVALID_HANDLE_VALUE)\r
7466                 {\r
7467                         // Windows 2000 以降\r
7468                         Zero(&device_info_data, sizeof(device_info_data));\r
7469                         device_info_data.cbSize = sizeof(device_info_data);\r
7470                         if (SetupDiCreateDeviceInfoW(device_info, inf_class_name, &inf_class_guid,\r
7471                                 NULL, NULL, DICD_GENERATE_ID, &device_info_data))\r
7472                         {\r
7473                                 // レジストリ情報を設定する\r
7474                                 if (SetupDiSetDeviceRegistryProperty(device_info, &device_info_data,\r
7475                                         SPDRP_HARDWAREID, (BYTE *)hwid, sizeof(hwid)))\r
7476                                 {\r
7477                                         NO_WARNING *nw = NULL;\r
7478                                         \r
7479                                         //if (MsIsVista() == false)\r
7480                                         {\r
7481                                                 nw = MsInitNoWarning();\r
7482                                         }\r
7483 \r
7484                                         // クラスインストーラを起動する\r
7485                                         if (SetupDiCallClassInstaller(DIF_REGISTERDEVICE, device_info,\r
7486                                                 &device_info_data))\r
7487                                         {\r
7488                                                 // インストールを行う\r
7489                                                 if (ms->nt->UpdateDriverForPlugAndPlayDevicesW(\r
7490                                                         NULL, hwid_w, infpath, 1, &need_reboot))\r
7491                                                 {\r
7492                                                         ret = true;\r
7493                                                 }\r
7494                                                 else\r
7495                                                 {\r
7496                                                         // インストール失敗\r
7497                                                         SetupDiCallClassInstaller(DIF_REMOVE, device_info,\r
7498                                                                 &device_info_data);\r
7499                                                 }\r
7500                                         }\r
7501                                         else\r
7502                                         {\r
7503                                                 Debug("SetupDiCallClassInstaller Error: %X\n", GetLastError());\r
7504                                         }\r
7505 \r
7506                                         MsFreeNoWarning(nw);\r
7507                                 }\r
7508                         }\r
7509                         // デバイス情報セットを削除する\r
7510                         SetupDiDestroyDeviceInfoList(device_info);\r
7511                 }\r
7512         }\r
7513 \r
7514         // インストール完了\r
7515         MsFinishDriverInstall(instance_name, sen_sys);\r
7516 \r
7517         for (i = 0;i < 5;i++)\r
7518         {\r
7519                 MsInitNetworkConfig(tag_name, instance_name, connection_tag_name);\r
7520                 SleepThread(MsIsVista() ? 1000 : 300);\r
7521         }\r
7522 \r
7523         if (ret)\r
7524         {\r
7525                 MsDisableVLan(instance_name);\r
7526                 MsEnableVLan(instance_name);\r
7527         }\r
7528 \r
7529         return ret;\r
7530 }\r
7531 \r
7532 // デバイス ID からデバイス情報を取得する\r
7533 HDEVINFO MsGetDevInfoFromDeviceId(SP_DEVINFO_DATA *dev_info_data, char *device_id)\r
7534 {\r
7535         HDEVINFO dev_info;\r
7536         SP_DEVINFO_LIST_DETAIL_DATA detail_data;\r
7537         SP_DEVINFO_DATA data;\r
7538         UINT i;\r
7539         bool found;\r
7540         char target_name[MAX_SIZE];\r
7541         // 引数チェック\r
7542         if (dev_info_data == NULL || device_id == NULL)\r
7543         {\r
7544                 return NULL;\r
7545         }\r
7546 \r
7547         StrCpy(target_name, sizeof(target_name), device_id);\r
7548 \r
7549         // デバイス情報リストを作成\r
7550         dev_info = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, NULL);\r
7551         if (dev_info == NULL)\r
7552         {\r
7553                 return NULL;\r
7554         }\r
7555 \r
7556         Zero(&detail_data, sizeof(detail_data));\r
7557         detail_data.cbSize = sizeof(detail_data);\r
7558         if (SetupDiGetDeviceInfoListDetail(dev_info, &detail_data) == false)\r
7559         {\r
7560                 MsDestroyDevInfo(dev_info);\r
7561                 return NULL;\r
7562         }\r
7563 \r
7564         Zero(&data, sizeof(data));\r
7565         data.cbSize = sizeof(data);\r
7566 \r
7567         // 列挙開始\r
7568         found = false;\r
7569         for (i = 0;SetupDiEnumDeviceInfo(dev_info, i, &data);i++)\r
7570         {\r
7571                 char *buffer;\r
7572                 UINT buffer_size = 8092;\r
7573                 DWORD data_type;\r
7574 \r
7575                 buffer = ZeroMalloc(buffer_size);\r
7576 \r
7577                 if (SetupDiGetDeviceRegistryProperty(dev_info, &data, SPDRP_HARDWAREID, &data_type, (PBYTE)buffer, buffer_size, NULL))\r
7578                 {\r
7579                         if (StrCmpi(buffer, target_name) == 0)\r
7580                         {\r
7581                                 // 発見\r
7582                                 found = true;\r
7583                         }\r
7584                 }\r
7585 \r
7586                 Free(buffer);\r
7587 \r
7588                 if (found)\r
7589                 {\r
7590                         break;\r
7591                 }\r
7592         }\r
7593 \r
7594         if (found == false)\r
7595         {\r
7596                 MsDestroyDevInfo(dev_info);\r
7597                 return NULL;\r
7598         }\r
7599         else\r
7600         {\r
7601                 Copy(dev_info_data, &data, sizeof(data));\r
7602                 return dev_info;\r
7603         }\r
7604 }\r
7605 \r
7606 // 指定したデバイスが動作中かどうかを調べる\r
7607 bool MsIsDeviceRunning(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)\r
7608 {\r
7609         SP_DEVINFO_LIST_DETAIL_DATA detail;\r
7610         UINT status = 0, problem = 0;\r
7611         // 引数チェック\r
7612         if (info == NULL || dev_info_data == NULL)\r
7613         {\r
7614                 return false;\r
7615         }\r
7616 \r
7617         Zero(&detail, sizeof(detail));\r
7618         detail.cbSize = sizeof(detail);\r
7619 \r
7620         if (SetupDiGetDeviceInfoListDetail(info, &detail) == false ||\r
7621                 ms->nt->CM_Get_DevNode_Status_Ex(&status, &problem, dev_info_data->DevInst,\r
7622                 0, detail.RemoteMachineHandle) != CR_SUCCESS)\r
7623         {\r
7624                 return false;\r
7625         }\r
7626 \r
7627         if (status & 8)\r
7628         {\r
7629                 return true;\r
7630         }\r
7631         else\r
7632         {\r
7633                 return false;\r
7634         }\r
7635 }\r
7636 \r
7637 // 指定したデバイスを開始させる\r
7638 bool MsStartDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)\r
7639 {\r
7640         SP_PROPCHANGE_PARAMS p;\r
7641         // 引数チェック\r
7642         if (info == NULL || dev_info_data == NULL)\r
7643         {\r
7644                 return false;\r
7645         }\r
7646 \r
7647         Zero(&p, sizeof(p));\r
7648         p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);\r
7649         p.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;\r
7650         p.StateChange = DICS_ENABLE;\r
7651         p.Scope = DICS_FLAG_GLOBAL;\r
7652         if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)))\r
7653         {\r
7654                 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, info, dev_info_data);\r
7655         }\r
7656 \r
7657         Zero(&p, sizeof(p));\r
7658         p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);\r
7659         p.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;\r
7660         p.StateChange = DICS_ENABLE;\r
7661         p.Scope = DICS_FLAG_CONFIGSPECIFIC;\r
7662 \r
7663         if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == false ||\r
7664                 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, info, dev_info_data) == false)\r
7665         {\r
7666                 return false;\r
7667         }\r
7668 \r
7669         return true;\r
7670 }\r
7671 \r
7672 // 指定したデバイスを停止させる\r
7673 bool MsStopDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)\r
7674 {\r
7675         SP_PROPCHANGE_PARAMS p;\r
7676         // 引数チェック\r
7677         if (info == NULL || dev_info_data == NULL)\r
7678         {\r
7679                 return false;\r
7680         }\r
7681 \r
7682         Zero(&p, sizeof(p));\r
7683         p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);\r
7684         p.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;\r
7685         p.StateChange = DICS_DISABLE;\r
7686         p.Scope = DICS_FLAG_CONFIGSPECIFIC;\r
7687 \r
7688         if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == false ||\r
7689                 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, info, dev_info_data) == false)\r
7690         {\r
7691                 return false;\r
7692         }\r
7693 \r
7694         return true;\r
7695 }\r
7696 \r
7697 // 指定したデバイスを削除する\r
7698 bool MsDeleteDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)\r
7699 {\r
7700         SP_REMOVEDEVICE_PARAMS p;\r
7701         SP_DEVINFO_LIST_DETAIL_DATA detail;\r
7702         char device_id[MAX_PATH];\r
7703         // 引数チェック\r
7704         if (info == NULL || dev_info_data == NULL)\r
7705         {\r
7706                 return false;\r
7707         }\r
7708 \r
7709         Zero(&detail, sizeof(detail));\r
7710         detail.cbSize = sizeof(detail);\r
7711 \r
7712         if (SetupDiGetDeviceInfoListDetail(info, &detail) == false ||\r
7713                 ms->nt->CM_Get_Device_ID_Ex(dev_info_data->DevInst, device_id, sizeof(device_id),\r
7714                 0, detail.RemoteMachineHandle) != CR_SUCCESS)\r
7715         {\r
7716                 return false;\r
7717         }\r
7718 \r
7719         Zero(&p, sizeof(p));\r
7720         p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);\r
7721         p.ClassInstallHeader.InstallFunction = DIF_REMOVE;\r
7722         p.Scope = DI_REMOVEDEVICE_GLOBAL;\r
7723 \r
7724         if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == false)\r
7725         {\r
7726                 Debug("SetupDiSetClassInstallParams Failed. Err=%u\n", GetLastError());\r
7727                 return false;\r
7728         }\r
7729 \r
7730         if (SetupDiCallClassInstaller(DIF_REMOVE, info, dev_info_data) == false)\r
7731         {\r
7732                 Debug("SetupDiCallClassInstaller Failed. Err=%u\n", GetLastError());\r
7733                 return false;\r
7734         }\r
7735 \r
7736         return true;\r
7737 }\r
7738 \r
7739 // 仮想 LAN カードを有効にする\r
7740 bool MsEnableVLan(char *instance_name)\r
7741 {\r
7742         char tmp[MAX_PATH];\r
7743         HDEVINFO h;\r
7744         bool ret;\r
7745         SP_DEVINFO_DATA data;\r
7746         // 引数チェック\r
7747         if (instance_name == NULL)\r
7748         {\r
7749                 return false;\r
7750         }\r
7751 \r
7752         if (MsIsNt() == false)\r
7753         {\r
7754                 return false;\r
7755         }\r
7756 \r
7757         Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);\r
7758 \r
7759         h = MsGetDevInfoFromDeviceId(&data, tmp);\r
7760         if (h == NULL)\r
7761         {\r
7762                 return false;\r
7763         }\r
7764 \r
7765         ret = MsStartDevice(h, &data);\r
7766 \r
7767         MsDestroyDevInfo(h);\r
7768 \r
7769         return ret;\r
7770 }\r
7771 \r
7772 // 仮想 LAN カードを無効にする\r
7773 bool MsDisableVLan(char *instance_name)\r
7774 {\r
7775         char tmp[MAX_PATH];\r
7776         HDEVINFO h;\r
7777         bool ret;\r
7778         SP_DEVINFO_DATA data;\r
7779         // 引数チェック\r
7780         if (instance_name == NULL)\r
7781         {\r
7782                 return false;\r
7783         }\r
7784 \r
7785         if (MsIsNt() == false)\r
7786         {\r
7787                 return false;\r
7788         }\r
7789 \r
7790         Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);\r
7791 \r
7792         h = MsGetDevInfoFromDeviceId(&data, tmp);\r
7793         if (h == NULL)\r
7794         {\r
7795                 return false;\r
7796         }\r
7797 \r
7798         ret = MsStopDevice(h, &data);\r
7799 \r
7800         MsDestroyDevInfo(h);\r
7801 \r
7802         return ret;\r
7803 }\r
7804 \r
7805 // 仮想 LAN カードを再起動する\r
7806 void MsRestartVLan(char *instance_name)\r
7807 {\r
7808         // 引数チェック\r
7809         if (instance_name == NULL)\r
7810         {\r
7811                 return;\r
7812         }\r
7813 \r
7814         if (MsIsNt() == false)\r
7815         {\r
7816                 return;\r
7817         }\r
7818 \r
7819         if (MsIsVLanEnabled(instance_name) == false)\r
7820         {\r
7821                 return;\r
7822         }\r
7823 \r
7824         MsDisableVLan(instance_name);\r
7825         MsEnableVLan(instance_name);\r
7826 }\r
7827 \r
7828 // 仮想 LAN カードが動作しているかどうか取得する\r
7829 bool MsIsVLanEnabled(char *instance_name)\r
7830 {\r
7831         char tmp[MAX_PATH];\r
7832         HDEVINFO h;\r
7833         bool ret;\r
7834         SP_DEVINFO_DATA data;\r
7835         // 引数チェック\r
7836         if (instance_name == NULL)\r
7837         {\r
7838                 return false;\r
7839         }\r
7840 \r
7841         if (MsIsNt() == false)\r
7842         {\r
7843                 return true;\r
7844         }\r
7845 \r
7846         Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);\r
7847 \r
7848         h = MsGetDevInfoFromDeviceId(&data, tmp);\r
7849         if (h == NULL)\r
7850         {\r
7851                 return false;\r
7852         }\r
7853 \r
7854         ret = MsIsDeviceRunning(h, &data);\r
7855 \r
7856         MsDestroyDevInfo(h);\r
7857 \r
7858         return ret;\r
7859 }\r
7860 \r
7861 // 仮想 LAN カードをアンインストールする\r
7862 bool MsUninstallVLan(char *instance_name)\r
7863 {\r
7864         char tmp[MAX_PATH];\r
7865         HDEVINFO h;\r
7866         bool ret;\r
7867         SP_DEVINFO_DATA data;\r
7868         // 引数チェック\r
7869         if (instance_name == NULL)\r
7870         {\r
7871                 return false;\r
7872         }\r
7873 \r
7874         Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);\r
7875 \r
7876         h = MsGetDevInfoFromDeviceId(&data, tmp);\r
7877         if (h == NULL)\r
7878         {\r
7879                 return false;\r
7880         }\r
7881 \r
7882         ret = MsDeleteDevice(h, &data);\r
7883 \r
7884         MsDestroyDevInfo(h);\r
7885 \r
7886         return ret;\r
7887 }\r
7888 \r
7889 // 汎用テスト関数\r
7890 void MsTest()\r
7891 {\r
7892 }\r
7893 \r
7894 // デバイス情報の破棄\r
7895 void MsDestroyDevInfo(HDEVINFO info)\r
7896 {\r
7897         // 引数チェック\r
7898         if (info == NULL)\r
7899         {\r
7900                 return;\r
7901         }\r
7902 \r
7903         SetupDiDestroyDeviceInfoList(info);\r
7904 }\r
7905 \r
7906 // ドライバインストールの開始\r
7907 bool MsStartDriverInstall(char *instance_name, UCHAR *mac_address, char *sen_sys)\r
7908 {\r
7909         wchar_t src_inf[MAX_PATH];\r
7910         wchar_t src_sys[MAX_PATH];\r
7911         wchar_t dest_inf[MAX_PATH];\r
7912         wchar_t dest_sys[MAX_PATH];\r
7913         UCHAR mac_address_bin[6];\r
7914         char mac_address_str[32];\r
7915         UINT size;\r
7916         char *tmp;\r
7917         BUF *b;\r
7918         IO *io;\r
7919         // 引数チェック\r
7920         if (instance_name == NULL || sen_sys == NULL)\r
7921         {\r
7922                 return false;\r
7923         }\r
7924 \r
7925         MsGetDriverPath(instance_name, src_inf, src_sys, dest_inf, dest_sys, sen_sys);\r
7926 \r
7927         // INF ファイルの処理\r
7928         io = FileOpenW(src_inf, false);\r
7929         if (io == NULL)\r
7930         {\r
7931                 return false;\r
7932         }\r
7933 \r
7934         size = FileSize(io);\r
7935         tmp = ZeroMalloc(size * 2);\r
7936         if (FileRead(io, tmp, size) == false)\r
7937         {\r
7938                 FileClose(io);\r
7939                 Free(tmp);\r
7940                 return false;\r
7941         }\r
7942 \r
7943         FileClose(io);\r
7944 \r
7945         if (mac_address == NULL)\r
7946         {\r
7947                 MsGenMacAddress(mac_address_bin);\r
7948         }\r
7949         else\r
7950         {\r
7951                 Copy(mac_address_bin, mac_address, 6);\r
7952         }\r
7953 \r
7954         BinToStr(mac_address_str, sizeof(mac_address_str), mac_address_bin, sizeof(mac_address_bin));\r
7955 \r
7956         //ReplaceStrEx(tmp, size * 2, tmp, "$TAG_DRIVER_VER$", DRIVER_VER_STR, false);\r
7957         ReplaceStrEx(tmp, size * 2, tmp, "$TAG_INSTANCE_NAME$", instance_name, false);\r
7958         ReplaceStrEx(tmp, size * 2, tmp, "$TAG_MAC_ADDRESS$", mac_address_str, false);\r
7959         ReplaceStrEx(tmp, size * 2, tmp, "$TAG_SYS_NAME$", sen_sys, false);\r
7960 \r
7961         if (MsIsVista())\r
7962         {\r
7963                 //ReplaceStrEx(tmp, size * 2, tmp, "\"100\"", "\"2000\"", false);\r
7964         }\r
7965 \r
7966         io = FileCreateW(dest_inf);\r
7967         if (io == NULL)\r
7968         {\r
7969                 Free(tmp);\r
7970                 return false;\r
7971         }\r
7972 \r
7973         FileWrite(io, tmp, StrLen(tmp));\r
7974         FileClose(io);\r
7975 \r
7976         Free(tmp);\r
7977 \r
7978         // SYS ファイルの処理\r
7979         b = ReadDumpW(src_sys);\r
7980         if (b == NULL)\r
7981         {\r
7982                 return false;\r
7983         }\r
7984 \r
7985         if (DumpBufW(b, dest_sys) == false)\r
7986         {\r
7987                 FreeBuf(b);\r
7988                 return false;\r
7989         }\r
7990 \r
7991         FreeBuf(b);\r
7992 \r
7993         return true;\r
7994 }\r
7995 \r
7996 // MAC アドレスの生成\r
7997 void MsGenMacAddress(UCHAR *mac)\r
7998 {\r
7999         UCHAR hash_src[40];\r
8000         UCHAR hash[20];\r
8001         UINT64 now;\r
8002         // 引数チェック\r
8003         if (mac == NULL)\r
8004         {\r
8005                 return;\r
8006         }\r
8007 \r
8008         Rand(hash_src, 40);\r
8009         now = SystemTime64();\r
8010         Copy(hash_src, &now, sizeof(now));\r
8011 \r
8012         Hash(hash, hash_src, sizeof(hash_src), true);\r
8013 \r
8014         mac[0] = 0x00;\r
8015         mac[1] = 0xAC;\r
8016         mac[2] = hash[0];\r
8017         mac[3] = hash[1];\r
8018         mac[4] = hash[2];\r
8019         mac[5] = hash[3];\r
8020 }\r
8021 \r
8022 // ドライバインストールの完了\r
8023 void MsFinishDriverInstall(char *instance_name, char *sen_sys)\r
8024 {\r
8025         wchar_t src_inf[MAX_PATH];\r
8026         wchar_t src_sys[MAX_PATH];\r
8027         wchar_t dest_inf[MAX_PATH];\r
8028         wchar_t dest_sys[MAX_PATH];\r
8029         // 引数チェック\r
8030         if (instance_name == NULL)\r
8031         {\r
8032                 return;\r
8033         }\r
8034 \r
8035         MsGetDriverPath(instance_name, src_inf, src_sys, dest_inf, dest_sys, sen_sys);\r
8036 \r
8037         // ファイル削除\r
8038         FileDeleteW(dest_inf);\r
8039         FileDeleteW(dest_sys);\r
8040 }\r
8041 \r
8042 // ドライバファイルのパスの取得\r
8043 void MsGetDriverPath(char *instance_name, wchar_t *src_inf, wchar_t *src_sys, wchar_t *dest_inf, wchar_t *dest_sys, char *sen_sys)\r
8044 {\r
8045         wchar_t *src_filename;\r
8046         wchar_t *src_sys_filename;\r
8047         // 引数チェック\r
8048         if (instance_name == NULL)\r
8049         {\r
8050                 return;\r
8051         }\r
8052 \r
8053         src_filename = DRIVER_INF_FILE_NAME;\r
8054         src_sys_filename = DRIVER_SYS_FILE_NAME;\r
8055 \r
8056         if (MsIsNt() == false)\r
8057         {\r
8058                 src_filename = DRIVER_INF_FILE_NAME_9X;\r
8059                 src_sys_filename = DRIVER_SYS_FILE_NAME_9X;\r
8060         }\r
8061         else if (MsIsIA64() || MsIsX64())\r
8062         {\r
8063                 if (MsIsX64())\r
8064                 {\r
8065                         src_filename = DRIVER_INF_FILE_NAME_X64;\r
8066                         src_sys_filename = DRIVER_SYS_FILE_NAME_X64;\r
8067                 }\r
8068                 else\r
8069                 {\r
8070                         src_filename = DRIVER_INF_FILE_NAME_IA64;\r
8071                         src_sys_filename = DRIVER_SYS_FILE_NAME_IA64;\r
8072                 }\r
8073         }\r
8074 \r
8075         if (src_inf != NULL)\r
8076         {\r
8077                 UniStrCpy(src_inf, MAX_PATH, src_filename);\r
8078         }\r
8079 \r
8080         if (src_sys != NULL)\r
8081         {\r
8082                 UniStrCpy(src_sys, MAX_PATH, src_sys_filename);\r
8083         }\r
8084 \r
8085         if (dest_inf != NULL)\r
8086         {\r
8087                 char inf_name[MAX_PATH];\r
8088                 Format(inf_name, sizeof(inf_name), DRIVER_INSTALL_INF_NAME_TAG, instance_name);\r
8089                 UniFormat(dest_inf, MAX_PATH, L"%s\\%S", ms->MyTempDirW, inf_name);\r
8090         }\r
8091 \r
8092         if (dest_sys != NULL)\r
8093         {\r
8094                 char sys_name[MAX_PATH];\r
8095                 StrCpy(sys_name, sizeof(sys_name), sen_sys);\r
8096                 UniFormat(dest_sys, MAX_PATH, L"%s\\%S", ms->MyTempDirW, sys_name);\r
8097         }\r
8098 }\r
8099 void MsGetDriverPathA(char *instance_name, char *src_inf, char *src_sys, char *dest_inf, char *dest_sys, char *sen_sys)\r
8100 {\r
8101         wchar_t src_inf_w[MAX_PATH];\r
8102         wchar_t src_sys_w[MAX_PATH];\r
8103         wchar_t dest_inf_w[MAX_PATH];\r
8104         wchar_t dest_sys_w[MAX_PATH];\r
8105 \r
8106         // 引数チェック\r
8107         if (instance_name == NULL)\r
8108         {\r
8109                 return;\r
8110         }\r
8111 \r
8112         MsGetDriverPath(instance_name, src_inf_w, src_sys_w, dest_inf_w, dest_sys_w, sen_sys);\r
8113 \r
8114         UniToStr(src_inf, MAX_PATH, src_inf_w);\r
8115         UniToStr(src_sys, MAX_PATH, src_sys_w);\r
8116         UniToStr(dest_inf, MAX_PATH, dest_inf_w);\r
8117         UniToStr(dest_sys, MAX_PATH, dest_sys_w);\r
8118 }\r
8119 \r
8120 // 指定された名前の仮想 LAN カードがすでに登録されているかどうかを調べる\r
8121 bool MsIsVLanExists(char *tag_name, char *instance_name)\r
8122 {\r
8123         char *guid;\r
8124         // 引数チェック\r
8125         if (instance_name == NULL || tag_name == NULL)\r
8126         {\r
8127                 return false;\r
8128         }\r
8129 \r
8130         guid = MsGetNetworkAdapterGuid(tag_name, instance_name);\r
8131         if (guid == NULL)\r
8132         {\r
8133                 return false;\r
8134         }\r
8135 \r
8136         Free(guid);\r
8137         return true;\r
8138 }\r
8139 \r
8140 // ネットワーク設定ダイアログを表示する\r
8141 // ※ これはもう使っていない。うまく動かないからである。\r
8142 //    代わりに ShowWindowsNetworkConnectionDialog() を使うこと。\r
8143 bool MsShowNetworkConfiguration(HWND hWnd)\r
8144 {\r
8145         IO *link_file = MsCreateTempFileByExt(".lnk");\r
8146         char name[MAX_PATH];\r
8147         SHELLEXECUTEINFO info;\r
8148 \r
8149         // ファイル名確保\r
8150         StrCpy(name, sizeof(name), link_file->Name);\r
8151 \r
8152         // ショートカット作成\r
8153         if (FileWrite(link_file, network_connection_link, sizeof(network_connection_link)) == false)\r
8154         {\r
8155                 FileCloseAndDelete(link_file);\r
8156                 return false;\r
8157         }\r
8158 \r
8159         FileClose(link_file);\r
8160 \r
8161         // ショートカットの実行\r
8162         Zero(&info, sizeof(info));\r
8163         info.cbSize = sizeof(info);\r
8164         info.hwnd = (HWND)hWnd;\r
8165         info.lpVerb = "open";\r
8166         info.lpFile = name;\r
8167         info.nShow = SW_SHOWDEFAULT;\r
8168         info.fMask = SEE_MASK_NOCLOSEPROCESS;\r
8169         if (ShellExecuteEx(&info) == false)\r
8170         {\r
8171                 FileDelete(name);\r
8172                 return false;\r
8173         }\r
8174 \r
8175         // プロセス終了まで待機\r
8176         WaitForSingleObject(info.hProcess, INFINITE);\r
8177         CloseHandle(info.hProcess);\r
8178 \r
8179         // ファイルの削除\r
8180         FileDelete(name);\r
8181 \r
8182         return true;\r
8183 }\r
8184 \r
8185 // 拡張子を元に一時ファイルを作成する\r
8186 IO *MsCreateTempFileByExt(char *ext)\r
8187 {\r
8188         char *tmp = MsCreateTempFileNameByExt(ext);\r
8189         IO *ret;\r
8190 \r
8191         if (tmp == NULL)\r
8192         {\r
8193                 return NULL;\r
8194         }\r
8195 \r
8196         ret = FileCreate(tmp);\r
8197         Free(tmp);\r
8198 \r
8199         return ret;\r
8200 }\r
8201 \r
8202 // 拡張子を指定するとその拡張子を持つ一時ファイルを作成する\r
8203 char *MsCreateTempFileNameByExt(char *ext)\r
8204 {\r
8205         UCHAR rand[2];\r
8206         char *ret = NULL;\r
8207         // 引数チェック\r
8208         if (ext == NULL)\r
8209         {\r
8210                 ext = "tmp";\r
8211         }\r
8212         if (ext[0] == '.')\r
8213         {\r
8214                 ext++;\r
8215         }\r
8216         if (StrLen(ext) == 0)\r
8217         {\r
8218                 ext = "tmp";\r
8219         }\r
8220 \r
8221         while (true)\r
8222         {\r
8223                 char new_filename[MAX_PATH];\r
8224                 char *fullpath;\r
8225                 char rand_str[MAX_PATH];\r
8226                 IO *io;\r
8227                 Rand(rand, sizeof(rand));\r
8228 \r
8229                 BinToStr(rand_str, sizeof(rand_str), rand, sizeof(rand));\r
8230                 Format(new_filename, sizeof(new_filename), "__%s.%s", rand_str, ext);\r
8231 \r
8232                 fullpath = MsCreateTempFileName(new_filename);\r
8233                 io = FileOpen(fullpath, false);\r
8234                 if (io == NULL)\r
8235                 {\r
8236                         ret = fullpath;\r
8237                         break;\r
8238                 }\r
8239                 FileClose(io);\r
8240 \r
8241                 Free(fullpath);\r
8242         }\r
8243 \r
8244         return ret;\r
8245 }\r
8246 \r
8247 // 一時ファイルを作成する\r
8248 IO *MsCreateTempFile(char *name)\r
8249 {\r
8250         IO *ret;\r
8251         char *tmp;\r
8252         // 引数チェック\r
8253         if (name == NULL)\r
8254         {\r
8255                 return NULL;\r
8256         }\r
8257 \r
8258         tmp = MsCreateTempFileName(name);\r
8259         if (tmp == NULL)\r
8260         {\r
8261                 return NULL;\r
8262         }\r
8263 \r
8264         ret = FileCreate(tmp);\r
8265         Free(tmp);\r
8266 \r
8267         return ret;\r
8268 }\r
8269 \r
8270 // 一時ファイル名を作成する\r
8271 char *MsCreateTempFileName(char *name)\r
8272 {\r
8273         char tmp[MAX_PATH];\r
8274         // 引数チェック\r
8275         if (name == NULL)\r
8276         {\r
8277                 return NULL;\r
8278         }\r
8279 \r
8280         Format(tmp, sizeof(tmp), "%s\\%s", ms->MyTempDir, name);\r
8281 \r
8282         return CopyStr(tmp);\r
8283 }\r
8284 \r
8285 // システムに残っているが使用されていない VPN 用一時ディレクトリを削除する\r
8286 void MsDeleteTempDir()\r
8287 {\r
8288         HANDLE h;\r
8289         wchar_t dir_mask[MAX_PATH];\r
8290         WIN32_FIND_DATAA data_a;\r
8291         WIN32_FIND_DATAW data_w;\r
8292 \r
8293         Zero(&data_a, sizeof(data_a));\r
8294         Zero(&data_w, sizeof(data_w));\r
8295 \r
8296         UniFormat(dir_mask, sizeof(dir_mask), L"%s\\*", ms->TempDirW);\r
8297 \r
8298         if (IsNt())\r
8299         {\r
8300                 h = FindFirstFileW(dir_mask, &data_w);\r
8301         }\r
8302         else\r
8303         {\r
8304                 char *tmp_a = CopyUniToStr(dir_mask);\r
8305 \r
8306                 h = FindFirstFileA(tmp_a, &data_a);\r
8307 \r
8308                 Free(tmp_a);\r
8309         }\r
8310 \r
8311         if (h != INVALID_HANDLE_VALUE)\r
8312         {\r
8313                 bool b = true;\r
8314 \r
8315                 do\r
8316                 {\r
8317                         if (IsNt() == false)\r
8318                         {\r
8319                                 Zero(&data_w, sizeof(data_w));\r
8320                                 StrToUni(data_w.cFileName, sizeof(data_w.cFileName), data_a.cFileName);\r
8321                                 data_w.dwFileAttributes = data_a.dwFileAttributes;\r
8322                                 data_w.ftCreationTime = data_a.ftCreationTime;\r
8323                                 data_w.ftLastWriteTime = data_a.ftLastWriteTime;\r
8324                                 data_w.nFileSizeHigh = data_a.nFileSizeHigh;\r
8325                                 data_w.nFileSizeLow = data_a.nFileSizeLow;\r
8326                         }\r
8327 \r
8328                         if (UniStrCmpi(data_w.cFileName, L".") != 0 &&\r
8329                                 UniStrCmpi(data_w.cFileName, L"..") != 0)\r
8330                         {\r
8331                                 if (data_w.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\r
8332                                 {\r
8333                                         if (UniStartWith(data_w.cFileName, L"VPN_") && UniStrLen(data_w.cFileName) == 8)\r
8334                                         {\r
8335                                                 wchar_t lock_file_name[MAX_PATH];\r
8336                                                 wchar_t dir_name[MAX_PATH];\r
8337                                                 bool delete_now = false;\r
8338                                                 IO *io;\r
8339 \r
8340                                                 UniFormat(dir_name, sizeof(dir_name), L"%s\\%s",\r
8341                                                         ms->TempDirW, data_w.cFileName);\r
8342                                                 MsGenLockFile(lock_file_name, sizeof(lock_file_name), dir_name);\r
8343 \r
8344                                                 io = FileOpenExW(lock_file_name, false, false);\r
8345                                                 if (io != NULL)\r
8346                                                 {\r
8347                                                         // ロックファイルがロックされていなければ削除マーク\r
8348                                                         FileClose(io);\r
8349                                                         io = FileOpenW(lock_file_name, true);\r
8350                                                         if (io != NULL)\r
8351                                                         {\r
8352                                                                 delete_now = true;\r
8353                                                                 FileClose(io);\r
8354                                                         }\r
8355                                                 }\r
8356                                                 else\r
8357                                                 {\r
8358                                                         DIRLIST *d;\r
8359 \r
8360                                                         // 中にあるすべてのファイルがロックされていなければ削除マーク\r
8361                                                         delete_now = true;\r
8362 \r
8363                                                         d = EnumDirW(dir_name);\r
8364                                                         if (d != NULL)\r
8365                                                         {\r
8366                                                                 UINT i;\r
8367 \r
8368                                                                 for (i = 0;i < d->NumFiles;i++)\r
8369                                                                 {\r
8370                                                                         wchar_t full_path[MAX_PATH];\r
8371 \r
8372                                                                         UniFormat(full_path, sizeof(full_path), L"%s\\%s", dir_name, d->File[i]->FileNameW);\r
8373 \r
8374                                                                         io = FileOpenW(full_path, true);\r
8375                                                                         if (io != NULL)\r
8376                                                                         {\r
8377                                                                                 delete_now = true;\r
8378                                                                                 FileClose(io);\r
8379                                                                         }\r
8380                                                                 }\r
8381                                                                 FreeDir(d);\r
8382                                                         }\r
8383                                                 }\r
8384                                                 if (delete_now)\r
8385                                                 {\r
8386                                                         MsDeleteAllFileW(dir_name);\r
8387 \r
8388                                                         Win32DeleteDirW(dir_name);\r
8389                                                 }\r
8390                                         }\r
8391                                 }\r
8392                         }\r
8393 \r
8394 \r
8395                         Zero(&data_w, sizeof(data_w));\r
8396                         Zero(&data_a, sizeof(data_a));\r
8397 \r
8398                         if (IsNt())\r
8399                         {\r
8400                                 b = FindNextFileW(h, &data_w);\r
8401                         }\r
8402                         else\r
8403                         {\r
8404                                 b = FindNextFileA(h, &data_a);\r
8405                         }\r
8406                 }\r
8407                 while (b);\r
8408 \r
8409                 FindClose(h);\r
8410         }\r
8411 }\r
8412 \r
8413 // 指定したディレクトリ内のファイルをすべて削除する\r
8414 void MsDeleteAllFile(char *dir)\r
8415 {\r
8416         HANDLE h;\r
8417         char file_mask[MAX_PATH];\r
8418         WIN32_FIND_DATA data;\r
8419         // 引数チェック\r
8420         if (dir == NULL || IsEmptyStr(dir))\r
8421         {\r
8422                 return;\r
8423         }\r
8424 \r
8425         Format(file_mask, sizeof(file_mask), "%s\\*.*", dir);\r
8426 \r
8427         h = FindFirstFile(file_mask, &data);\r
8428         if (h != INVALID_HANDLE_VALUE)\r
8429         {\r
8430                 do\r
8431                 {\r
8432                         if (StrCmpi(data.cFileName, ".") != 0 &&\r
8433                                 StrCmpi(data.cFileName, "..") != 0)\r
8434                         {\r
8435                                 char fullpath[MAX_PATH];\r
8436                                 Format(fullpath, sizeof(fullpath), "%s\\%s", dir, data.cFileName);\r
8437                                 if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == false)\r
8438                                 {\r
8439                                         DeleteFile(fullpath);\r
8440                                 }\r
8441                                 else\r
8442                                 {\r
8443                                         MsDeleteAllFile(fullpath);\r
8444                                         RemoveDirectory(fullpath);\r
8445                                 }\r
8446                         }\r
8447                 }\r
8448                 while (FindNextFile(h, &data));\r
8449 \r
8450                 FindClose(h);\r
8451         }\r
8452 }\r
8453 void MsDeleteAllFileW(wchar_t *dir)\r
8454 {\r
8455         HANDLE h;\r
8456         wchar_t file_mask[MAX_PATH];\r
8457         WIN32_FIND_DATAW data;\r
8458         // 引数チェック\r
8459         if (dir == NULL || UniIsEmptyStr(dir))\r
8460         {\r
8461                 return;\r
8462         }\r
8463 \r
8464         if (IsNt() == false)\r
8465         {\r
8466                 char *dir_a = CopyUniToStr(dir);\r
8467 \r
8468                 MsDeleteAllFile(dir_a);\r
8469 \r
8470                 Free(dir_a);\r
8471 \r
8472                 return;\r
8473         }\r
8474 \r
8475         UniFormat(file_mask, sizeof(file_mask), L"%s\\*.*", dir);\r
8476 \r
8477         h = FindFirstFileW(file_mask, &data);\r
8478         if (h != INVALID_HANDLE_VALUE)\r
8479         {\r
8480                 do\r
8481                 {\r
8482                         if (UniStrCmpi(data.cFileName, L".") != 0 &&\r
8483                                 UniStrCmpi(data.cFileName, L"..") != 0)\r
8484                         {\r
8485                                 wchar_t fullpath[MAX_PATH];\r
8486 \r
8487                                 UniFormat(fullpath, sizeof(fullpath), L"%s\\%s", dir, data.cFileName);\r
8488 \r
8489                                 if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == false)\r
8490                                 {\r
8491                                         DeleteFileW(fullpath);\r
8492                                 }\r
8493                                 else\r
8494                                 {\r
8495                                         MsDeleteAllFileW(fullpath);\r
8496                                         RemoveDirectoryW(fullpath);\r
8497                                 }\r
8498                         }\r
8499                 }\r
8500                 while (FindNextFileW(h, &data));\r
8501 \r
8502                 FindClose(h);\r
8503         }\r
8504 }\r
8505 \r
8506 // 一時ディレクトリを初期化する\r
8507 void MsInitTempDir()\r
8508 {\r
8509         wchar_t tmp[MAX_PATH];\r
8510         wchar_t tmp2[16];\r
8511         UCHAR random[2];\r
8512         wchar_t lockfilename[MAX_PATH];\r
8513         UINT num = 0;\r
8514 \r
8515         // 使われていない一時ディレクトリの削除\r
8516         MsDeleteTempDir();\r
8517 \r
8518         // 一時ディレクトリ名の決定\r
8519         while (true)\r
8520         {\r
8521                 random[0] = rand() % 256;\r
8522                 random[1] = rand() % 256;\r
8523                 BinToStrW(tmp2, sizeof(tmp2), random, sizeof(random));\r
8524 \r
8525                 UniFormat(tmp, sizeof(tmp), L"%s\\VPN_%s", ms->TempDirW, tmp2);\r
8526 \r
8527                 // ディレクトリの作成\r
8528                 if (MakeDirW(tmp))\r
8529                 {\r
8530                         break;\r
8531                 }\r
8532 \r
8533                 if ((num++) >= 100)\r
8534                 {\r
8535                         // 何度も失敗する\r
8536                         char msg[MAX_SIZE];\r
8537                         Format(msg, sizeof(msg),\r
8538                                 "Couldn't create Temporary Directory: %s\r\n\r\n"\r
8539                                 "Please contact your system administrator.",\r
8540                                 tmp);\r
8541                         exit(0);\r
8542                 }\r
8543         }\r
8544 \r
8545         ms->MyTempDirW = CopyUniStr(tmp);\r
8546         ms->MyTempDir = CopyUniToStr(tmp);\r
8547 \r
8548         // ロックファイルの作成\r
8549         MsGenLockFile(lockfilename, sizeof(lockfilename), ms->MyTempDirW);\r
8550         ms->LockFile = FileCreateW(lockfilename);\r
8551 }\r
8552 \r
8553 // 一時ディレクトリを解放する\r
8554 void MsFreeTempDir()\r
8555 {\r
8556         wchar_t lock_file_name[MAX_SIZE];\r
8557 \r
8558         // ロックファイルの削除\r
8559         MsGenLockFile(lock_file_name, sizeof(lock_file_name), ms->MyTempDirW);\r
8560         FileClose(ms->LockFile);\r
8561 \r
8562         // メモリ解放\r
8563         Free(ms->MyTempDir);\r
8564         Free(ms->MyTempDirW);\r
8565         ms->MyTempDir = NULL;\r
8566         ms->MyTempDirW = NULL;\r
8567 \r
8568         // ディレクトリ削除\r
8569         MsDeleteTempDir();\r
8570 }\r
8571 \r
8572 // ロックファイル名の生成\r
8573 void MsGenLockFile(wchar_t *name, UINT size, wchar_t *temp_dir)\r
8574 {\r
8575         // 引数チェック\r
8576         if (name == NULL || temp_dir == NULL)\r
8577         {\r
8578                 return;\r
8579         }\r
8580 \r
8581         UniFormat(name, size, L"%s\\VPN_Lock.dat", temp_dir);\r
8582 }\r
8583 \r
8584 // ネットワーク設定の初期化\r
8585 void MsInitNetworkConfig(char *tag_name, char *instance_name, char *connection_tag_name)\r
8586 {\r
8587         char tmp[MAX_SIZE];\r
8588         char *config_str;\r
8589         // 引数チェック\r
8590         if (tag_name == NULL || instance_name == NULL || connection_tag_name == NULL)\r
8591         {\r
8592                 return;\r
8593         }\r
8594 \r
8595         if (MsIsNt() == false)\r
8596         {\r
8597                 return;\r
8598         }\r
8599 \r
8600         // 文字列などの設定\r
8601         Format(tmp, sizeof(tmp), connection_tag_name, instance_name);\r
8602         MsSetNetworkConfig(tag_name, instance_name, tmp, true);\r
8603 \r
8604         // インターフェイス・メトリック値の設定\r
8605         config_str = MsGetNetworkAdapterGuid(tag_name, instance_name);\r
8606         if (config_str != NULL)\r
8607         {\r
8608                 Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",\r
8609                         config_str);\r
8610 \r
8611                 MsRegWriteInt(REG_LOCAL_MACHINE, tmp, "InterfaceMetric", 1);\r
8612                 MsRegWriteInt(REG_LOCAL_MACHINE, tmp, "EnableDeadGWDetect", 0);\r
8613 \r
8614                 if (MsRegReadInt(REG_LOCAL_MACHINE,\r
8615                         "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
8616                         "packetix_no_optimize") == 0)\r
8617                 {\r
8618                         MsRegWriteInt(REG_LOCAL_MACHINE,\r
8619                                 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
8620                                 "EnableDeadGWDetect",\r
8621                                 0);\r
8622                 }\r
8623 \r
8624                 Free(config_str);\r
8625         }\r
8626 }\r
8627 \r
8628 // ネットワーク設定を行う\r
8629 void MsSetNetworkConfig(char *tag_name, char *instance_name, char *friendly_name, bool show_icon)\r
8630 {\r
8631         char *key;\r
8632         char *old_name;\r
8633         // 引数チェック\r
8634         if (tag_name == NULL || instance_name == NULL || friendly_name == NULL)\r
8635         {\r
8636                 return;\r
8637         }\r
8638 \r
8639         key = MsGetNetworkConfigRegKeyNameFromInstanceName(tag_name, instance_name);\r
8640         if (key == NULL)\r
8641         {\r
8642                 return;\r
8643         }\r
8644 \r
8645         old_name = MsRegReadStr(REG_LOCAL_MACHINE, key, "Name");\r
8646         if (old_name != NULL)\r
8647         {\r
8648                 if (MsIsVista())\r
8649                 {\r
8650                         char arg[MAX_PATH];\r
8651                         char netsh[MAX_PATH];\r
8652 \r
8653                         Format(netsh, sizeof(netsh), "%s\\netsh.exe", MsGetSystem32Dir());\r
8654 \r
8655                         if (StrCmp(old_name, friendly_name) != 0)\r
8656                         {\r
8657                                 Format(arg, sizeof(arg), "interface set interface name=\"%s\" newname=\"%s\"",\r
8658                                         old_name, friendly_name);\r
8659 \r
8660                                 Run(netsh, arg, true, true);\r
8661                         }\r
8662 \r
8663                         Format(arg, sizeof(arg), "netsh interface ipv4 set interface interface=\"%s\" metric=1",\r
8664                                 friendly_name);\r
8665 \r
8666                         Run(netsh, arg, true, true);\r
8667                 }\r
8668         }\r
8669 \r
8670         if (StrCmp(old_name, friendly_name) != 0)\r
8671         {\r
8672                 MsRegWriteStr(REG_LOCAL_MACHINE, key, "Name", friendly_name);\r
8673         }\r
8674 \r
8675         MsRegWriteInt(REG_LOCAL_MACHINE, key, "ShowIcon", show_icon ? 1 : 0);\r
8676 \r
8677         Free(key);\r
8678 \r
8679         Free(old_name);\r
8680 }\r
8681 \r
8682 // ネットワーク設定キー名をインスタンス名から取得\r
8683 char *MsGetNetworkConfigRegKeyNameFromInstanceName(char *tag_name, char *instance_name)\r
8684 {\r
8685         char *guid, *ret;\r
8686         // 引数チェック\r
8687         if (tag_name == NULL || instance_name == NULL)\r
8688         {\r
8689                 return NULL;\r
8690         }\r
8691 \r
8692         guid = MsGetNetworkAdapterGuid(tag_name, instance_name);\r
8693         if (guid == NULL)\r
8694         {\r
8695                 return NULL;\r
8696         }\r
8697 \r
8698         ret = MsGetNetworkConfigRegKeyNameFromGuid(guid);\r
8699 \r
8700         Free(guid);\r
8701 \r
8702         return ret;\r
8703 }\r
8704 \r
8705 // ネットワーク設定キー名を GUID から取得\r
8706 char *MsGetNetworkConfigRegKeyNameFromGuid(char *guid)\r
8707 {\r
8708         char tmp[MAX_SIZE];\r
8709         // 引数チェック\r
8710         if (guid == NULL)\r
8711         {\r
8712                 return NULL;\r
8713         }\r
8714 \r
8715         Format(tmp, sizeof(tmp),\r
8716                 "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection",\r
8717                 guid);\r
8718 \r
8719         return CopyStr(tmp);\r
8720 }\r
8721 \r
8722 // MAC アドレスの設定\r
8723 void MsSetMacAddress(char *tag_name, char *instance_name, char *mac_address)\r
8724 {\r
8725         TOKEN_LIST *key_list;\r
8726         UINT i;\r
8727         char dest_name[MAX_SIZE];\r
8728         char mac_str[MAX_SIZE];\r
8729         // 引数チェック\r
8730         if (tag_name == NULL || instance_name == NULL)\r
8731         {\r
8732                 return;\r
8733         }\r
8734 \r
8735         // MAC アドレスの正規化\r
8736         if (NormalizeMacAddress(mac_str, sizeof(mac_str), mac_address) == false)\r
8737         {\r
8738                 return;\r
8739         }\r
8740 \r
8741         // 目的の名前を生成\r
8742         Format(dest_name, sizeof(dest_name), tag_name, instance_name);\r
8743 \r
8744         // キーを列挙\r
8745         if (MsIsNt())\r
8746         {\r
8747                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
8748                         "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");\r
8749         }\r
8750         else\r
8751         {\r
8752                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
8753                         "System\\CurrentControlSet\\Services\\Class\\Net");\r
8754         }\r
8755         if (key_list == NULL)\r
8756         {\r
8757                 return;\r
8758         }\r
8759 \r
8760         for (i = 0;i < key_list->NumTokens;i++)\r
8761         {\r
8762                 char *key_name = key_list->Token[i];\r
8763                 char full_key_name[MAX_SIZE];\r
8764                 char *driver_desc;\r
8765 \r
8766                 if (MsIsNt())\r
8767                 {\r
8768                         Format(full_key_name, sizeof(full_key_name),\r
8769                                 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",\r
8770                                 key_name);\r
8771                 }\r
8772                 else\r
8773                 {\r
8774                         Format(full_key_name, sizeof(full_key_name),\r
8775                                 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",\r
8776                                 key_name);\r
8777                 }\r
8778 \r
8779                 // DriverDesc を読み込む\r
8780                 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");\r
8781                 if (driver_desc != NULL)\r
8782                 {\r
8783                         if (StrCmpi(dest_name, driver_desc) == 0)\r
8784                         {\r
8785                                 // MAC アドレスの書き込み\r
8786                                 MsRegWriteStr(REG_LOCAL_MACHINE, full_key_name, "NetworkAddress", mac_str);\r
8787                                 Free(driver_desc);\r
8788 \r
8789                                 // ドライバの再起動\r
8790                                 MsRestartVLan(instance_name);\r
8791                                 break;\r
8792                         }\r
8793                         Free(driver_desc);\r
8794                 }\r
8795         }\r
8796 \r
8797         FreeToken(key_list);\r
8798 \r
8799         return;\r
8800 }\r
8801 \r
8802 // デバイスドライバのファイル名の取得\r
8803 char *MsGetDriverFileName(char *tag_name, char *instance_name)\r
8804 {\r
8805         TOKEN_LIST *key_list;\r
8806         UINT i;\r
8807         char *ret = NULL;\r
8808         char dest_name[MAX_SIZE];\r
8809         // 引数チェック\r
8810         if (tag_name == NULL || instance_name == NULL)\r
8811         {\r
8812                 return NULL;\r
8813         }\r
8814 \r
8815         // 目的の名前を生成\r
8816         Format(dest_name, sizeof(dest_name), tag_name, instance_name);\r
8817 \r
8818         // キーを列挙\r
8819         if (MsIsNt())\r
8820         {\r
8821                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
8822                         "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");\r
8823         }\r
8824         else\r
8825         {\r
8826                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
8827                         "System\\CurrentControlSet\\Services\\Class\\Net");\r
8828         }\r
8829         if (key_list == NULL)\r
8830         {\r
8831                 return NULL;\r
8832         }\r
8833 \r
8834         for (i = 0;i < key_list->NumTokens;i++)\r
8835         {\r
8836                 char *key_name = key_list->Token[i];\r
8837                 char full_key_name[MAX_SIZE];\r
8838                 char *driver_desc;\r
8839 \r
8840                 if (MsIsNt())\r
8841                 {\r
8842                         Format(full_key_name, sizeof(full_key_name),\r
8843                                 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",\r
8844                                 key_name);\r
8845                 }\r
8846                 else\r
8847                 {\r
8848                         Format(full_key_name, sizeof(full_key_name),\r
8849                                 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",\r
8850                                 key_name);\r
8851                 }\r
8852 \r
8853                 // DriverDesc を読み込む\r
8854                 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");\r
8855                 if (driver_desc != NULL)\r
8856                 {\r
8857                         if (StrCmpi(dest_name, driver_desc) == 0)\r
8858                         {\r
8859                                 // ファイル名を読み込む\r
8860                                 ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DeviceVxDs");\r
8861                                 Free(driver_desc);\r
8862                                 break;\r
8863                         }\r
8864                         Free(driver_desc);\r
8865                 }\r
8866         }\r
8867 \r
8868         FreeToken(key_list);\r
8869 \r
8870         return ret;\r
8871 }\r
8872 \r
8873 // デバイスドライバのバージョンの取得\r
8874 char *MsGetDriverVersion(char *tag_name, char *instance_name)\r
8875 {\r
8876         TOKEN_LIST *key_list;\r
8877         TOKEN_LIST *t;\r
8878         UINT i;\r
8879         char *ret = NULL;\r
8880         char dest_name[MAX_SIZE];\r
8881         // 引数チェック\r
8882         if (tag_name == NULL || instance_name == NULL)\r
8883         {\r
8884                 return NULL;\r
8885         }\r
8886 \r
8887         // 目的の名前を生成\r
8888         Format(dest_name, sizeof(dest_name), tag_name, instance_name);\r
8889 \r
8890         // キーを列挙\r
8891         if (MsIsNt())\r
8892         {\r
8893                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
8894                         "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");\r
8895         }\r
8896         else\r
8897         {\r
8898                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
8899                         "System\\CurrentControlSet\\Services\\Class\\Net");\r
8900         }\r
8901         if (key_list == NULL)\r
8902         {\r
8903                 return NULL;\r
8904         }\r
8905 \r
8906         for (i = 0;i < key_list->NumTokens;i++)\r
8907         {\r
8908                 char *key_name = key_list->Token[i];\r
8909                 char full_key_name[MAX_SIZE];\r
8910                 char *driver_desc;\r
8911 \r
8912                 if (MsIsNt())\r
8913                 {\r
8914                         Format(full_key_name, sizeof(full_key_name),\r
8915                                 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",\r
8916                                 key_name);\r
8917                 }\r
8918                 else\r
8919                 {\r
8920                         Format(full_key_name, sizeof(full_key_name),\r
8921                                 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",\r
8922                                 key_name);\r
8923                 }\r
8924 \r
8925                 // DriverDesc を読み込む\r
8926                 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");\r
8927                 if (driver_desc != NULL)\r
8928                 {\r
8929                         if (StrCmpi(dest_name, driver_desc) == 0)\r
8930                         {\r
8931                                 // バージョン情報を読み込む\r
8932                                 ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverVersion");\r
8933                                 if (ret == NULL)\r
8934                                 {\r
8935                                         ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "SenVersion");\r
8936                                 }\r
8937                                 Free(driver_desc);\r
8938                                 break;\r
8939                         }\r
8940                         Free(driver_desc);\r
8941                 }\r
8942         }\r
8943 \r
8944         FreeToken(key_list);\r
8945 \r
8946         if (ret == NULL)\r
8947         {\r
8948                 return NULL;\r
8949         }\r
8950 \r
8951         t = ParseToken(ret, ", ");\r
8952         if (t->NumTokens == 2)\r
8953         {\r
8954                 Free(ret);\r
8955                 ret = CopyStr(t->Token[1]);\r
8956         }\r
8957         FreeToken(t);\r
8958 \r
8959         return ret;\r
8960 }\r
8961 \r
8962 // MAC アドレスの取得\r
8963 char *MsGetMacAddress(char *tag_name, char *instance_name)\r
8964 {\r
8965         TOKEN_LIST *key_list;\r
8966         UINT i;\r
8967         char *ret = NULL;\r
8968         char dest_name[MAX_SIZE];\r
8969         // 引数チェック\r
8970         if (tag_name == NULL || instance_name == NULL)\r
8971         {\r
8972                 return NULL;\r
8973         }\r
8974 \r
8975         // 目的の名前を生成\r
8976         Format(dest_name, sizeof(dest_name), tag_name, instance_name);\r
8977 \r
8978         // キーを列挙\r
8979         if (MsIsNt())\r
8980         {\r
8981                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
8982                         "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");\r
8983         }\r
8984         else\r
8985         {\r
8986                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
8987                         "System\\CurrentControlSet\\Services\\Class\\Net");\r
8988         }\r
8989 \r
8990         if (key_list == NULL)\r
8991         {\r
8992                 return NULL;\r
8993         }\r
8994 \r
8995         for (i = 0;i < key_list->NumTokens;i++)\r
8996         {\r
8997                 char *key_name = key_list->Token[i];\r
8998                 char full_key_name[MAX_SIZE];\r
8999                 char *driver_desc;\r
9000 \r
9001                 if (MsIsNt())\r
9002                 {\r
9003                         Format(full_key_name, sizeof(full_key_name),\r
9004                                 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",\r
9005                                 key_name);\r
9006                 }\r
9007                 else\r
9008                 {\r
9009                         Format(full_key_name, sizeof(full_key_name),\r
9010                                 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",\r
9011                                 key_name);\r
9012                 }\r
9013 \r
9014                 // DriverDesc を読み込む\r
9015                 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");\r
9016                 if (driver_desc != NULL)\r
9017                 {\r
9018                         if (StrCmpi(dest_name, driver_desc) == 0)\r
9019                         {\r
9020                                 // MAC アドレスを読み込む\r
9021                                 ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "NetworkAddress");\r
9022 \r
9023                                 if (IsEmptyStr(ret) == false)\r
9024                                 {\r
9025                                         // MAC アドレスにハイフンを入れる\r
9026                                         BUF *b = StrToBin(ret);\r
9027                                         if (b != NULL && b->Size == 6)\r
9028                                         {\r
9029                                                 char tmp[MAX_SIZE];\r
9030                                                 MacToStr(tmp, sizeof(tmp), b->Buf);\r
9031 \r
9032                                                 Free(ret);\r
9033                                                 ret = CopyStr(tmp);\r
9034                                         }\r
9035                                         FreeBuf(b);\r
9036                                 }\r
9037 \r
9038                                 Free(driver_desc);\r
9039                                 break;\r
9040                         }\r
9041                         Free(driver_desc);\r
9042                 }\r
9043         }\r
9044 \r
9045         FreeToken(key_list);\r
9046 \r
9047         return ret;\r
9048 }\r
9049 \r
9050 // 仮想 LAN カードのデバイス名が本当に存在するかどうかチェックする\r
9051 bool MsCheckVLanDeviceIdFromRootEnum(char *name)\r
9052 {\r
9053         TOKEN_LIST *t;\r
9054         char *root;\r
9055         char *keyname;\r
9056         UINT i;\r
9057         bool ret;\r
9058         // 引数チェック\r
9059         if (name == NULL)\r
9060         {\r
9061                 return false;\r
9062         }\r
9063 \r
9064         if (MsIsNt())\r
9065         {\r
9066                 root = "SYSTEM\\CurrentControlSet\\Enum\\Root\\NET";\r
9067                 keyname = "HardwareID";\r
9068         }\r
9069         else\r
9070         {\r
9071                 root = "Enum\\Root\\Net";\r
9072                 keyname = "CompatibleIDs";\r
9073         }\r
9074 \r
9075         t = MsRegEnumKey(REG_LOCAL_MACHINE, root);\r
9076         if (t == NULL)\r
9077         {\r
9078                 return false;\r
9079         }\r
9080 \r
9081         ret = false;\r
9082 \r
9083         for (i = 0;i < t->NumTokens;i++)\r
9084         {\r
9085                 char *subname = t->Token[i];\r
9086                 char fullname[MAX_SIZE];\r
9087                 char *value;\r
9088 \r
9089                 Format(fullname, sizeof(fullname), "%s\\%s", root, subname);\r
9090 \r
9091                 value = MsRegReadStr(REG_LOCAL_MACHINE, fullname, keyname);\r
9092                 if (value != NULL)\r
9093                 {\r
9094                         if (StrCmpi(value, name) == 0)\r
9095                         {\r
9096                                 ret = true;\r
9097                         }\r
9098                         Free(value);\r
9099                 }\r
9100 \r
9101                 if (ret)\r
9102                 {\r
9103                         break;\r
9104                 }\r
9105         }\r
9106 \r
9107         FreeToken(t);\r
9108 \r
9109         return ret;\r
9110 }\r
9111 \r
9112 // ネットワークアダプタの GUID の取得\r
9113 char *MsGetNetworkAdapterGuid(char *tag_name, char *instance_name)\r
9114 {\r
9115         TOKEN_LIST *key_list;\r
9116         UINT i;\r
9117         char *ret = NULL;\r
9118         char dest_name[MAX_SIZE];\r
9119         // 引数チェック\r
9120         if (tag_name == NULL || instance_name == NULL)\r
9121         {\r
9122                 return NULL;\r
9123         }\r
9124 \r
9125         // 目的の名前を生成\r
9126         Format(dest_name, sizeof(dest_name), tag_name, instance_name);\r
9127 \r
9128         // キーを列挙\r
9129         if (MsIsNt())\r
9130         {\r
9131                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
9132                         "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");\r
9133         }\r
9134         else\r
9135         {\r
9136                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
9137                         "System\\CurrentControlSet\\Services\\Class\\Net");\r
9138         }\r
9139         if (key_list == NULL)\r
9140         {\r
9141                 return NULL;\r
9142         }\r
9143 \r
9144         for (i = 0;i < key_list->NumTokens;i++)\r
9145         {\r
9146                 char *key_name = key_list->Token[i];\r
9147                 char full_key_name[MAX_SIZE];\r
9148                 char *driver_desc;\r
9149                 char *device_id;\r
9150 \r
9151                 if (MsIsNt())\r
9152                 {\r
9153                         Format(full_key_name, sizeof(full_key_name),\r
9154                                 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",\r
9155                                 key_name);\r
9156                 }\r
9157                 else\r
9158                 {\r
9159                         Format(full_key_name, sizeof(full_key_name),\r
9160                                 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",\r
9161                                 key_name);\r
9162                 }\r
9163 \r
9164                 device_id = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "MatchingDeviceId");\r
9165 \r
9166                 if (device_id != NULL)\r
9167                 {\r
9168                         if (MsCheckVLanDeviceIdFromRootEnum(device_id))\r
9169                         {\r
9170                                 // DriverDesc を読み込む\r
9171                                 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");\r
9172                                 if (driver_desc != NULL)\r
9173                                 {\r
9174                                         if (StrCmpi(dest_name, driver_desc) == 0)\r
9175                                         {\r
9176                                                 // NetCfgInstanceId を読み込む\r
9177                                                 if (MsIsNt())\r
9178                                                 {\r
9179                                                         ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "NetCfgInstanceId");\r
9180                                                 }\r
9181                                                 else\r
9182                                                 {\r
9183                                                         ret = CopyStr("");\r
9184                                                 }\r
9185                                                 Free(driver_desc);\r
9186                                                 Free(device_id);\r
9187                                                 break;\r
9188                                         }\r
9189                                         Free(driver_desc);\r
9190                                 }\r
9191                         }\r
9192                         Free(device_id);\r
9193                 }\r
9194         }\r
9195 \r
9196         FreeToken(key_list);\r
9197 \r
9198         return ret;\r
9199 }\r
9200 // ネットワーク接続名の取得\r
9201 wchar_t *MsGetNetworkConnectionName(char *guid)\r
9202 {\r
9203         wchar_t *ncname = NULL;\r
9204         // 引数チェック\r
9205         if (guid == NULL)\r
9206         {\r
9207                 return NULL;\r
9208         }\r
9209 \r
9210         // ネットワーク接続名を取得\r
9211         if (IsNt() != false && GetOsInfo()->OsType >= OSTYPE_WINDOWS_2000_PROFESSIONAL)\r
9212         {\r
9213                 char tmp[MAX_SIZE];\r
9214                 Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", guid);\r
9215                 ncname = MsRegReadStrW(REG_LOCAL_MACHINE, tmp, "Name");\r
9216         }\r
9217 \r
9218         return ncname;\r
9219 }\r
9220 \r
9221 // 新しい Sen のドライバファイル名を生成\r
9222 bool MsMakeNewSenDriverFilename(char *name, UINT size)\r
9223 {\r
9224         TOKEN_LIST *t = MsEnumSenDriverFilenames();\r
9225         UINT i;\r
9226         bool ret = false;\r
9227 \r
9228         i = 0;\r
9229         while (true)\r
9230         {\r
9231                 char tmp[MAX_PATH];\r
9232                 UINT n;\r
9233 \r
9234                 i++;\r
9235                 if (i >= 10000)\r
9236                 {\r
9237                         break;\r
9238                 }\r
9239 \r
9240                 n = Rand32() % DRIVER_INSTALL_SYS_NAME_TAG_MAXID;\r
9241 \r
9242                 MsGenerateSenDriverFilenameFromInt(tmp, sizeof(tmp), n);\r
9243 \r
9244                 if (IsInToken(t, tmp) == false)\r
9245                 {\r
9246                         StrCpy(name, size, tmp);\r
9247                         ret = true;\r
9248                         break;\r
9249                 }\r
9250         }\r
9251 \r
9252         FreeToken(t);\r
9253 \r
9254         return ret;\r
9255 }\r
9256 \r
9257 // Sen のドライバファイル名を整数から生成\r
9258 void MsGenerateSenDriverFilenameFromInt(char *name, UINT size, UINT n)\r
9259 {\r
9260         Format(name, size, DRIVER_INSTALL_SYS_NAME_TAG_NEW, n);\r
9261 }\r
9262 \r
9263 // インストールされている Sen のドライバファイル名の列挙\r
9264 TOKEN_LIST *MsEnumSenDriverFilenames()\r
9265 {\r
9266         TOKEN_LIST *neos = MsEnumNetworkAdaptersSen();\r
9267         LIST *o = NewListFast(NULL);\r
9268         TOKEN_LIST *ret;\r
9269         UINT i;\r
9270 \r
9271         for (i = 0;i < neos->NumTokens;i++)\r
9272         {\r
9273                 char filename[MAX_PATH];\r
9274                 if (MsGetSenDeiverFilename(filename, sizeof(filename), neos->Token[i]))\r
9275                 {\r
9276                         Add(o, CopyStr(filename));\r
9277                 }\r
9278         }\r
9279 \r
9280         FreeToken(neos);\r
9281 \r
9282         ret = ListToTokenList(o);\r
9283         FreeStrList(o);\r
9284 \r
9285         return ret;\r
9286 }\r
9287 \r
9288 // Sen のドライバファイル名を取得\r
9289 bool MsGetSenDeiverFilename(char *name, UINT size, char *instance_name)\r
9290 {\r
9291         char tmp[MAX_SIZE];\r
9292         char *ret;\r
9293         // 引数チェック\r
9294         if (name == NULL || instance_name == NULL)\r
9295         {\r
9296                 return false;\r
9297         }\r
9298 \r
9299         Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Services\\Sen_%s", instance_name);\r
9300 \r
9301         ret = MsRegReadStr(REG_LOCAL_MACHINE, tmp, "ImagePath");\r
9302         if (ret == NULL)\r
9303         {\r
9304                 return false;\r
9305         }\r
9306 \r
9307         GetFileNameFromFilePath(name, size, ret);\r
9308         Free(ret);\r
9309 \r
9310         return true;\r
9311 }\r
9312 \r
9313 // ネットワークアダプタの列挙 (Sen のみ)\r
9314 TOKEN_LIST *MsEnumNetworkAdaptersSen()\r
9315 {\r
9316         TOKEN_LIST *key_list;\r
9317         TOKEN_LIST *ret;\r
9318         LIST *o;\r
9319         UINT i;\r
9320 \r
9321         // キーを列挙\r
9322         if (MsIsNt())\r
9323         {\r
9324                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
9325                         "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");\r
9326         }\r
9327         else\r
9328         {\r
9329                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
9330                         "System\\CurrentControlSet\\Services\\Class\\Net");\r
9331         }\r
9332         if (key_list == NULL)\r
9333         {\r
9334                 return NULL;\r
9335         }\r
9336 \r
9337         o = NewListFast(CompareStr);\r
9338 \r
9339         for (i = 0;i < key_list->NumTokens;i++)\r
9340         {\r
9341                 char *key_name = key_list->Token[i];\r
9342                 char full_key_name[MAX_SIZE];\r
9343                 char *driver_desc;\r
9344                 char *device_id;\r
9345 \r
9346                 if (MsIsNt())\r
9347                 {\r
9348                         Format(full_key_name, sizeof(full_key_name),\r
9349                                 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",\r
9350                                 key_name);\r
9351                 }\r
9352                 else\r
9353                 {\r
9354                         Format(full_key_name, sizeof(full_key_name),\r
9355                                 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",\r
9356                                 key_name);\r
9357                 }\r
9358 \r
9359                 // DriverDesc を読み込む\r
9360                 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");\r
9361                 if (driver_desc != NULL)\r
9362                 {\r
9363                         // 特定の名前で始まっているかどうか確認する\r
9364                         device_id = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "MatchingDeviceId");\r
9365 \r
9366                         if (device_id != NULL)\r
9367                         {\r
9368                                 if (MsCheckVLanDeviceIdFromRootEnum(device_id))\r
9369                                 {\r
9370                                         char *tag = "senadapter_";\r
9371                                         if (StartWith(device_id, tag))\r
9372                                         {\r
9373                                                 char tmp[MAX_SIZE];\r
9374                                                 StrCpy(tmp, sizeof(tmp), &device_id[StrLen(tag)]);\r
9375 \r
9376                                                 Add(o, CopyStr(tmp));\r
9377                                         }\r
9378                                 }\r
9379                                 Free(device_id);\r
9380                         }\r
9381 \r
9382                         Free(driver_desc);\r
9383                 }\r
9384         }\r
9385 \r
9386         FreeToken(key_list);\r
9387 \r
9388         ret = ZeroMalloc(sizeof(TOKEN_LIST));\r
9389         ret->NumTokens = LIST_NUM(o);\r
9390         ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);\r
9391         for (i = 0;i < ret->NumTokens;i++)\r
9392         {\r
9393                 ret->Token[i] = LIST_DATA(o, i);\r
9394         }\r
9395 \r
9396         ReleaseList(o);\r
9397 \r
9398         return ret;\r
9399 }\r
9400 \r
9401 // ネットワークアダプタの列挙\r
9402 TOKEN_LIST *MsEnumNetworkAdapters(char *start_with_name, char *start_with_name_2)\r
9403 {\r
9404         TOKEN_LIST *key_list;\r
9405         TOKEN_LIST *ret;\r
9406         LIST *o;\r
9407         UINT i;\r
9408 \r
9409         // キーを列挙\r
9410         if (MsIsNt())\r
9411         {\r
9412                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
9413                         "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");\r
9414         }\r
9415         else\r
9416         {\r
9417                 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,\r
9418                         "System\\CurrentControlSet\\Services\\Class\\Net");\r
9419         }\r
9420         if (key_list == NULL)\r
9421         {\r
9422                 return NULL;\r
9423         }\r
9424 \r
9425         o = NewListFast(CompareStr);\r
9426 \r
9427         for (i = 0;i < key_list->NumTokens;i++)\r
9428         {\r
9429                 char *key_name = key_list->Token[i];\r
9430                 char full_key_name[MAX_SIZE];\r
9431                 char *driver_desc;\r
9432                 char *device_id;\r
9433 \r
9434                 if (MsIsNt())\r
9435                 {\r
9436                         Format(full_key_name, sizeof(full_key_name),\r
9437                                 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",\r
9438                                 key_name);\r
9439                 }\r
9440                 else\r
9441                 {\r
9442                         Format(full_key_name, sizeof(full_key_name),\r
9443                                 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",\r
9444                                 key_name);\r
9445                 }\r
9446 \r
9447                 // DriverDesc を読み込む\r
9448                 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");\r
9449                 if (driver_desc != NULL)\r
9450                 {\r
9451                         // 特定の名前で始まっているかどうか確認する\r
9452                         if ((IsEmptyStr(start_with_name) && IsEmptyStr(start_with_name_2)) ||\r
9453                                 (StartWith(driver_desc, start_with_name) || StartWith(driver_desc, start_with_name_2)))\r
9454                         {\r
9455                                 device_id = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "MatchingDeviceId");\r
9456 \r
9457                                 if (device_id != NULL)\r
9458                                 {\r
9459                                         if (MsCheckVLanDeviceIdFromRootEnum(device_id))\r
9460                                         {\r
9461                                                 char instance_name[MAX_SIZE];\r
9462                                                 // 名前からインスタンス名だけを抽出する\r
9463                                                 if (StartWith(driver_desc, start_with_name))\r
9464                                                 {\r
9465                                                         if (StrLen(driver_desc) > (StrLen(start_with_name) + 3))\r
9466                                                         {\r
9467                                                                 StrCpy(instance_name, sizeof(instance_name),\r
9468                                                                         driver_desc + StrLen(start_with_name) + 3);\r
9469                                                                 Add(o, CopyStr(instance_name));\r
9470                                                         }\r
9471                                                 }\r
9472                                                 else\r
9473                                                 {\r
9474                                                         if (StrLen(driver_desc) > (StrLen(start_with_name_2) + 3))\r
9475                                                         {\r
9476                                                                 StrCpy(instance_name, sizeof(instance_name),\r
9477                                                                         driver_desc + StrLen(start_with_name_2) + 3);\r
9478                                                                 Add(o, CopyStr(instance_name));\r
9479                                                         }\r
9480                                                 }\r
9481                                         }\r
9482                                         Free(device_id);\r
9483                                 }\r
9484                         }\r
9485 \r
9486                         Free(driver_desc);\r
9487                 }\r
9488         }\r
9489 \r
9490         FreeToken(key_list);\r
9491 \r
9492         ret = ZeroMalloc(sizeof(TOKEN_LIST));\r
9493         ret->NumTokens = LIST_NUM(o);\r
9494         ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);\r
9495         for (i = 0;i < ret->NumTokens;i++)\r
9496         {\r
9497                 ret->Token[i] = LIST_DATA(o, i);\r
9498         }\r
9499 \r
9500         ReleaseList(o);\r
9501 \r
9502         return ret;\r
9503 }\r
9504 \r
9505 // ドメインへのログオンを試行する\r
9506 bool MsCheckLogon(wchar_t *username, char *password)\r
9507 {\r
9508         wchar_t password_unicode[MAX_SIZE];\r
9509         HANDLE h;\r
9510         // 引数チェック\r
9511         if (username == NULL || password == NULL)\r
9512         {\r
9513                 return false;\r
9514         }\r
9515 \r
9516         if (MsIsNt() == false)\r
9517         {\r
9518                 return false;\r
9519         }\r
9520 \r
9521         StrToUni(password_unicode, sizeof(password_unicode), password);\r
9522 \r
9523         if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)\r
9524         {\r
9525                 if (ms->nt->LogonUserW(username, NULL, password_unicode, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)\r
9526                 {\r
9527                         // ログオン失敗\r
9528                         return false;\r
9529                 }\r
9530         }\r
9531         else\r
9532         {\r
9533                 char username_ansi[MAX_SIZE];\r
9534                 UniToStr(username_ansi, sizeof(username_ansi), username);\r
9535 \r
9536                 if (ms->nt->LogonUserA(username_ansi, NULL, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)\r
9537                 {\r
9538                         // ログオン失敗\r
9539                         return false;\r
9540                 }\r
9541         }\r
9542 \r
9543         CloseHandle(h);\r
9544 \r
9545         return true;\r
9546 }\r
9547 \r
9548 // ドメインへのログオンを試行する\r
9549 bool MsIsPasswordEmpty(wchar_t *username)\r
9550 {\r
9551         HANDLE h;\r
9552         // 引数チェック\r
9553         if (username == NULL)\r
9554         {\r
9555                 return false;\r
9556         }\r
9557 \r
9558         if (MsIsNt() == false)\r
9559         {\r
9560                 return false;\r
9561         }\r
9562 \r
9563         if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)\r
9564         {\r
9565                 if (ms->nt->LogonUserW(username, NULL, L"", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)\r
9566                 {\r
9567                         // ログオン失敗\r
9568                         if (GetLastError() == 1327)\r
9569                         {\r
9570                                 // パスワードが空\r
9571                                 return true;\r
9572                         }\r
9573                         else\r
9574                         {\r
9575                                 // パスワードが間違っている\r
9576                                 return false;\r
9577                         }\r
9578                 }\r
9579         }\r
9580         else\r
9581         {\r
9582                 char username_ansi[MAX_SIZE];\r
9583                 UniToStr(username_ansi, sizeof(username_ansi), username);\r
9584 \r
9585                 if (ms->nt->LogonUserA(username_ansi, NULL, "", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)\r
9586                 {\r
9587                         // ログオン失敗\r
9588                         if (GetLastError() == 1327)\r
9589                         {\r
9590                                 // パスワードが空\r
9591                                 return true;\r
9592                         }\r
9593                         else\r
9594                         {\r
9595                                 // パスワードが間違っている\r
9596                                 return false;\r
9597                         }\r
9598                 }\r
9599         }\r
9600 \r
9601         CloseHandle(h);\r
9602 \r
9603         // ログオン成功ということはパスワードが空ということになる\r
9604         return false;\r
9605 }\r
9606 \r
9607 // シャットダウンの実行 (NT)\r
9608 bool MsShutdownEx(bool reboot, bool force, UINT time_limit, char *message)\r
9609 {\r
9610         if (MsIsNt() == false)\r
9611         {\r
9612                 return MsShutdown(reboot, force);\r
9613         }\r
9614 \r
9615         // 特権の取得\r
9616         if (MsEnablePrivilege(SE_SHUTDOWN_NAME, true) == false)\r
9617         {\r
9618                 return false;\r
9619         }\r
9620 \r
9621         // シャットダウンの実行\r
9622         if (ms->nt->InitiateSystemShutdown(NULL, message, time_limit, force, reboot) == false)\r
9623         {\r
9624                 MsEnablePrivilege(SE_SHUTDOWN_NAME, false);\r
9625                 return false;\r
9626         }\r
9627 \r
9628         // 特権の解放\r
9629         MsEnablePrivilege(SE_SHUTDOWN_NAME, false);\r
9630 \r
9631         return true;\r
9632 }\r
9633 \r
9634 // シャットダウンの実行\r
9635 bool MsShutdown(bool reboot, bool force)\r
9636 {\r
9637         UINT flag = 0;\r
9638         // 特権の取得\r
9639         if (MsEnablePrivilege(SE_SHUTDOWN_NAME, true) == false)\r
9640         {\r
9641                 return false;\r
9642         }\r
9643 \r
9644         flag |= (reboot ? EWX_REBOOT : EWX_SHUTDOWN);\r
9645         flag |= (force ? EWX_FORCE : 0);\r
9646 \r
9647         // シャットダウンの実行\r
9648         if (ExitWindowsEx(flag, 0) == false)\r
9649         {\r
9650                 MsEnablePrivilege(SE_SHUTDOWN_NAME, false);\r
9651                 return false;\r
9652         }\r
9653 \r
9654         // 特権の解放\r
9655         MsEnablePrivilege(SE_SHUTDOWN_NAME, false);\r
9656 \r
9657         return true;\r
9658 }\r
9659 \r
9660 // 特権を有効または無効にする\r
9661 bool MsEnablePrivilege(char *name, bool enable)\r
9662 {\r
9663         HANDLE hToken;\r
9664         NT_API *nt = ms->nt;\r
9665         LUID luid;\r
9666         TOKEN_PRIVILEGES *tp;\r
9667         bool ret;\r
9668         // 引数チェック\r
9669         if (name == NULL)\r
9670         {\r
9671                 return false;\r
9672         }\r
9673         if (MsIsNt() == false)\r
9674         {\r
9675                 return true;\r
9676         }\r
9677 \r
9678         // プロセストークンを開く\r
9679         if (nt->OpenProcessToken(ms->hCurrentProcess, TOKEN_ADJUST_PRIVILEGES, &hToken) == false)\r
9680         {\r
9681                 return false;\r
9682         }\r
9683 \r
9684         // ローカル一意識別子を取得する\r
9685         if (nt->LookupPrivilegeValue(NULL, name, &luid) == FALSE)\r
9686         {\r
9687                 CloseHandle(hToken);\r
9688                 return false;\r
9689         }\r
9690 \r
9691         // 特権を有効 / 無効にするための構造体を作成する\r
9692         tp = ZeroMalloc(sizeof(TOKEN_PRIVILEGES));\r
9693         tp->PrivilegeCount = 1;\r
9694         tp->Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;\r
9695         Copy(&tp->Privileges[0].Luid, &luid, sizeof(LUID));\r
9696 \r
9697         // 特権を操作する\r
9698         ret = nt->AdjustTokenPrivileges(hToken, false, tp, sizeof(TOKEN_PRIVILEGES), 0, 0);\r
9699 \r
9700         Free(tp);\r
9701         CloseHandle(hToken);\r
9702 \r
9703         return ret;\r
9704 }\r
9705 \r
9706 // 現在の OS が NT 系かどうか取得\r
9707 bool MsIsNt()\r
9708 {\r
9709         if (ms == NULL)\r
9710         {\r
9711                 OSVERSIONINFO os;\r
9712                 Zero(&os, sizeof(os));\r
9713                 os.dwOSVersionInfoSize = sizeof(os);\r
9714                 GetVersionEx(&os);\r
9715                 if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)\r
9716                 {\r
9717                         return true;\r
9718                 }\r
9719                 else\r
9720                 {\r
9721                         return false;\r
9722                 }\r
9723         }\r
9724 \r
9725         return ms->IsNt;\r
9726 }\r
9727 \r
9728 // 現在のユーザーが Admin かどうか取得\r
9729 bool MsIsAdmin()\r
9730 {\r
9731         return ms->IsAdmin;\r
9732 }\r
9733 \r
9734 // NT 系関数のロード\r
9735 NT_API *MsLoadNtApiFunctions()\r
9736 {\r
9737         NT_API *nt = ZeroMalloc(sizeof(NT_API));\r
9738         OSVERSIONINFO info;\r
9739 \r
9740         Zero(&info, sizeof(info));\r
9741         info.dwOSVersionInfoSize = sizeof(info);\r
9742         GetVersionEx(&info);\r
9743 \r
9744         nt->hKernel32 = LoadLibrary("kernel32.dll");\r
9745         if (nt->hKernel32 == NULL)\r
9746         {\r
9747                 Free(nt);\r
9748                 return NULL;\r
9749         }\r
9750 \r
9751         nt->hAdvapi32 = LoadLibrary("advapi32.dll");\r
9752         if (nt->hAdvapi32 == NULL)\r
9753         {\r
9754                 Free(nt);\r
9755                 return NULL;\r
9756         }\r
9757 \r
9758         nt->hShell32 = LoadLibrary("shell32.dll");\r
9759         if (nt->hShell32 == NULL)\r
9760         {\r
9761                 FreeLibrary(nt->hAdvapi32);\r
9762                 Free(nt);\r
9763                 return NULL;\r
9764         }\r
9765 \r
9766         nt->hPsApi = LoadLibrary("psapi.dll");\r
9767 \r
9768         if (info.dwMajorVersion >= 5)\r
9769         {\r
9770                 nt->hNewDev = LoadLibrary("newdev.dll");\r
9771                 if (nt->hNewDev == NULL)\r
9772                 {\r
9773                         FreeLibrary(nt->hShell32);\r
9774                         FreeLibrary(nt->hAdvapi32);\r
9775                         Free(nt);\r
9776                         return NULL;\r
9777                 }\r
9778 \r
9779                 nt->hSetupApi = LoadLibrary("setupapi.dll");\r
9780         }\r
9781 \r
9782         nt->hSecur32 = LoadLibrary("secur32.dll");\r
9783 \r
9784         nt->hUser32 = LoadLibrary("user32.dll");\r
9785 \r
9786         nt->hDbgHelp = LoadLibrary("dbghelp.dll");\r
9787 \r
9788         // 関数の読み込み\r
9789         nt->IsWow64Process =\r
9790                 (BOOL (__stdcall *)(HANDLE,BOOL *))\r
9791                 GetProcAddress(nt->hKernel32, "IsWow64Process");\r
9792 \r
9793         nt->GetFileInformationByHandle =\r
9794                 (BOOL (__stdcall *)(HANDLE,LPBY_HANDLE_FILE_INFORMATION))\r
9795                 GetProcAddress(nt->hKernel32, "GetFileInformationByHandle");\r
9796 \r
9797         nt->GetProcessHeap =\r
9798                 (HANDLE (__stdcall *)())\r
9799                 GetProcAddress(nt->hKernel32, "GetProcessHeap");\r
9800 \r
9801         nt->SetProcessShutdownParameters =\r
9802                 (BOOL (__stdcall *)(DWORD,DWORD))\r
9803                 GetProcAddress(nt->hKernel32, "SetProcessShutdownParameters");\r
9804 \r
9805         nt->GetNativeSystemInfo =\r
9806                 (void (__stdcall *)(SYSTEM_INFO *))\r
9807                 GetProcAddress(nt->hKernel32, "GetNativeSystemInfo");\r
9808 \r
9809         nt->AdjustTokenPrivileges =\r
9810                 (BOOL (__stdcall *)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD))\r
9811                 GetProcAddress(nt->hAdvapi32, "AdjustTokenPrivileges");\r
9812 \r
9813         nt->LookupPrivilegeValue =\r
9814                 (BOOL (__stdcall *)(char *,char *,PLUID))\r
9815                 GetProcAddress(nt->hAdvapi32, "LookupPrivilegeValueA");\r
9816 \r
9817         nt->OpenProcessToken =\r
9818                 (BOOL (__stdcall *)(HANDLE,DWORD,PHANDLE))\r
9819                 GetProcAddress(nt->hAdvapi32, "OpenProcessToken");\r
9820 \r
9821         nt->InitiateSystemShutdown =\r
9822                 (BOOL (__stdcall *)(LPTSTR,LPTSTR,DWORD,BOOL,BOOL))\r
9823                 GetProcAddress(nt->hAdvapi32, "InitiateSystemShutdownA");\r
9824 \r
9825         nt->LogonUserW =\r
9826                 (BOOL (__stdcall *)(wchar_t *,wchar_t *,wchar_t *,DWORD,DWORD,HANDLE *))\r
9827                 GetProcAddress(nt->hAdvapi32, "LogonUserW");\r
9828 \r
9829         nt->LogonUserA =\r
9830                 (BOOL (__stdcall *)(char *,char *,char *,DWORD,DWORD,HANDLE * ))\r
9831                 GetProcAddress(nt->hAdvapi32, "LogonUserA");\r
9832 \r
9833         nt->DuplicateTokenEx =\r
9834                 (BOOL (__stdcall *)(HANDLE,DWORD,SECURITY_ATTRIBUTES *,SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,HANDLE *))\r
9835                 GetProcAddress(nt->hAdvapi32, "DuplicateTokenEx");\r
9836 \r
9837         nt->ConvertStringSidToSidA =\r
9838                 (BOOL (__stdcall *)(LPCSTR,PSID *))\r
9839                 GetProcAddress(nt->hAdvapi32, "ConvertStringSidToSidA");\r
9840 \r
9841         nt->GetTokenInformation =\r
9842                 (BOOL (__stdcall *)(HANDLE,TOKEN_INFORMATION_CLASS,void *,DWORD,PDWORD))\r
9843                 GetProcAddress(nt->hAdvapi32, "GetTokenInformation");\r
9844 \r
9845         nt->SetTokenInformation =\r
9846                 (BOOL (__stdcall *)(HANDLE,TOKEN_INFORMATION_CLASS,void *,DWORD))\r
9847                 GetProcAddress(nt->hAdvapi32, "SetTokenInformation");\r
9848 \r
9849         nt->CreateProcessAsUserA =\r
9850                 (BOOL (__stdcall *)(HANDLE,LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,void *,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION))\r
9851                 GetProcAddress(nt->hAdvapi32, "CreateProcessAsUserA");\r
9852 \r
9853         nt->CreateProcessAsUserW =\r
9854                 (BOOL (__stdcall *)(HANDLE,LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,void *,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION))\r
9855                 GetProcAddress(nt->hAdvapi32, "CreateProcessAsUserW");\r
9856 \r
9857         nt->LookupAccountSidA =\r
9858                 (BOOL (__stdcall *)(LPCSTR,PSID,LPSTR,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE))\r
9859                 GetProcAddress(nt->hAdvapi32, "LookupAccountSidA");\r
9860 \r
9861         nt->LookupAccountNameA =\r
9862                 (BOOL (__stdcall *)(LPCSTR,LPCSTR,PSID,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE))\r
9863                 GetProcAddress(nt->hAdvapi32, "LookupAccountNameA");\r
9864 \r
9865         if (info.dwMajorVersion >= 5)\r
9866         {\r
9867                 nt->UpdateDriverForPlugAndPlayDevicesW =\r
9868                         (BOOL (__stdcall *)(HWND,wchar_t *,wchar_t *,UINT,BOOL *))\r
9869                         GetProcAddress(nt->hNewDev, "UpdateDriverForPlugAndPlayDevicesW");\r
9870 \r
9871                 nt->CM_Get_Device_ID_ExA =\r
9872                         (UINT (__stdcall *)(DWORD,char *,UINT,UINT,HANDLE))\r
9873                         GetProcAddress(nt->hSetupApi, "CM_Get_Device_ID_ExA");\r
9874 \r
9875                 nt->CM_Get_DevNode_Status_Ex =\r
9876                         (UINT (__stdcall *)(UINT *,UINT *,DWORD,UINT,HANDLE))\r
9877                         GetProcAddress(nt->hSetupApi, "CM_Get_DevNode_Status_Ex");\r
9878         }\r
9879 \r
9880         nt->hWtsApi32 = LoadLibrary("wtsapi32.dll");\r
9881         if (nt->hWtsApi32 != NULL)\r
9882         {\r
9883                 // ターミナルサービス関係の API\r
9884                 nt->WTSQuerySessionInformation =\r
9885                         (UINT (__stdcall *)(HANDLE,DWORD,WTS_INFO_CLASS,wchar_t *,DWORD *))\r
9886                         GetProcAddress(nt->hWtsApi32, "WTSQuerySessionInformationW");\r
9887                 nt->WTSFreeMemory =\r
9888                         (void (__stdcall *)(void *))\r
9889                         GetProcAddress(nt->hWtsApi32, "WTSFreeMemory");\r
9890                 nt->WTSDisconnectSession =\r
9891                         (BOOL (__stdcall *)(HANDLE,DWORD,BOOL))\r
9892                         GetProcAddress(nt->hWtsApi32, "WTSDisconnectSession");\r
9893                 nt->WTSEnumerateSessionsA =\r
9894                         (BOOL (__stdcall *)(HANDLE,DWORD,DWORD,PWTS_SESSION_INFOA *,DWORD *))\r
9895                         GetProcAddress(nt->hWtsApi32, "WTSEnumerateSessionsA");\r
9896         }\r
9897 \r
9898         // サービス系 API\r
9899         nt->OpenSCManager =\r
9900                 (SC_HANDLE (__stdcall *)(LPCTSTR,LPCTSTR,DWORD))\r
9901                 GetProcAddress(nt->hAdvapi32, "OpenSCManagerA");\r
9902         nt->CreateServiceA =\r
9903                 (SC_HANDLE (__stdcall *)(SC_HANDLE,LPCTSTR,LPCTSTR,DWORD,DWORD,DWORD,DWORD,LPCTSTR,LPCTSTR,LPDWORD,LPCTSTR,LPCTSTR,LPCTSTR))\r
9904                 GetProcAddress(nt->hAdvapi32, "CreateServiceA");\r
9905         nt->CreateServiceW =\r
9906                 (SC_HANDLE (__stdcall *)(SC_HANDLE,LPCWSTR,LPCWSTR,DWORD,DWORD,DWORD,DWORD,LPCWSTR,LPCWSTR,LPDWORD,LPCWSTR,LPCWSTR,LPCWSTR))\r
9907                 GetProcAddress(nt->hAdvapi32, "CreateServiceW");\r
9908         nt->ChangeServiceConfig2 =\r
9909                 (BOOL (__stdcall *)(SC_HANDLE,DWORD,LPVOID))\r
9910                 GetProcAddress(nt->hAdvapi32, "ChangeServiceConfig2W");\r
9911         nt->CloseServiceHandle =\r
9912                 (BOOL (__stdcall *)(SC_HANDLE))\r
9913                 GetProcAddress(nt->hAdvapi32, "CloseServiceHandle");\r
9914         nt->OpenService =\r
9915                 (SC_HANDLE (__stdcall *)(SC_HANDLE,LPCTSTR,DWORD))\r
9916                 GetProcAddress(nt->hAdvapi32, "OpenServiceA");\r
9917         nt->QueryServiceStatus =\r
9918                 (BOOL (__stdcall *)(SC_HANDLE,LPSERVICE_STATUS))\r
9919                 GetProcAddress(nt->hAdvapi32, "QueryServiceStatus");\r
9920         nt->StartService =\r
9921                 (BOOL (__stdcall *)(SC_HANDLE,DWORD,LPCTSTR))\r
9922                 GetProcAddress(nt->hAdvapi32, "StartServiceA");\r
9923         nt->ControlService =\r
9924                 (BOOL (__stdcall *)(SC_HANDLE,DWORD,LPSERVICE_STATUS))\r
9925                 GetProcAddress(nt->hAdvapi32, "ControlService");\r
9926         nt->SetServiceStatus =\r
9927                 (BOOL (__stdcall *)(SERVICE_STATUS_HANDLE,LPSERVICE_STATUS))\r
9928                 GetProcAddress(nt->hAdvapi32, "SetServiceStatus");\r
9929         nt->RegisterServiceCtrlHandler =\r
9930                 (SERVICE_STATUS_HANDLE (__stdcall *)(LPCTSTR,LPHANDLER_FUNCTION))\r
9931                 GetProcAddress(nt->hAdvapi32, "RegisterServiceCtrlHandlerW");\r
9932         nt->StartServiceCtrlDispatcher =\r
9933                 (BOOL (__stdcall *)(const LPSERVICE_TABLE_ENTRY))\r
9934                 GetProcAddress(nt->hAdvapi32, "StartServiceCtrlDispatcherW");\r
9935         nt->DeleteService =\r
9936                 (BOOL (__stdcall *)(SC_HANDLE))\r
9937                 GetProcAddress(nt->hAdvapi32, "DeleteService");\r
9938         nt->RegisterEventSourceW =\r
9939                 (HANDLE (__stdcall *)(LPCWSTR,LPCWSTR))\r
9940                 GetProcAddress(nt->hAdvapi32, "RegisterEventSourceW");\r
9941         nt->ReportEventW =\r
9942                 (BOOL (__stdcall *)(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCWSTR *,LPVOID))\r
9943                 GetProcAddress(nt->hAdvapi32, "ReportEventW");\r
9944         nt->DeregisterEventSource =\r
9945                 (BOOL (__stdcall *)(HANDLE))\r
9946                 GetProcAddress(nt->hAdvapi32, "DeregisterEventSource");\r
9947         nt->Wow64DisableWow64FsRedirection =\r
9948                 (BOOL (__stdcall *)(void **))\r
9949                 GetProcAddress(nt->hKernel32, "Wow64DisableWow64FsRedirection");\r
9950         nt->Wow64EnableWow64FsRedirection =\r
9951                 (BOOLEAN (__stdcall *)(BOOLEAN))\r
9952                 GetProcAddress(nt->hKernel32, "Wow64EnableWow64FsRedirection");\r
9953         nt->Wow64RevertWow64FsRedirection =\r
9954                 (BOOL (__stdcall *)(void *))\r
9955                 GetProcAddress(nt->hKernel32, "Wow64RevertWow64FsRedirection");\r
9956 \r
9957         if (nt->hPsApi != NULL)\r
9958         {\r
9959                 // プロセス系 API\r
9960                 nt->EnumProcesses =\r
9961                         (BOOL (__stdcall *)(DWORD *,DWORD,DWORD *))\r
9962                         GetProcAddress(nt->hPsApi, "EnumProcesses");\r
9963 \r
9964                 nt->EnumProcessModules =\r
9965                         (BOOL (__stdcall *)(HANDLE,HMODULE * ,DWORD,DWORD *))\r
9966                         GetProcAddress(nt->hPsApi, "EnumProcessModules");\r
9967 \r
9968                 nt->GetModuleFileNameExA =\r
9969                         (DWORD (__stdcall *)(HANDLE,HMODULE,LPSTR,DWORD))\r
9970                         GetProcAddress(nt->hPsApi, "GetModuleFileNameExA");\r
9971 \r
9972                 nt->GetModuleFileNameExW =\r
9973                         (DWORD (__stdcall *)(HANDLE,HMODULE,LPWSTR,DWORD))\r
9974                         GetProcAddress(nt->hPsApi, "GetModuleFileNameExW");\r
9975         }\r
9976 \r
9977         // レジストリ系 API\r
9978         nt->RegDeleteKeyExA =\r
9979                 (LONG (__stdcall *)(HKEY,LPCTSTR,REGSAM,DWORD))\r
9980                 GetProcAddress(nt->hAdvapi32, "RegDeleteKeyExA");\r
9981 \r
9982         // セキュリティ系 API\r
9983         if (nt->hSecur32 != NULL)\r
9984         {\r
9985                 nt->GetUserNameExA =\r
9986                         (BOOL (__stdcall *)(EXTENDED_NAME_FORMAT,LPSTR,PULONG))\r
9987                         GetProcAddress(nt->hSecur32, "GetUserNameExA");\r
9988 \r
9989                 nt->GetUserNameExW =\r
9990                         (BOOL (__stdcall *)(EXTENDED_NAME_FORMAT,LPWSTR,PULONG))\r
9991                         GetProcAddress(nt->hSecur32, "GetUserNameExW");\r
9992         }\r
9993 \r
9994         // デスクトップ系 API\r
9995         if (nt->hUser32 != NULL)\r
9996         {\r
9997                 nt->SwitchDesktop =\r
9998                         (BOOL (__stdcall *)(HDESK))\r
9999                         GetProcAddress(nt->hUser32, "SwitchDesktop");\r
10000                 nt->OpenDesktopA =\r
10001                         (HDESK (__stdcall *)(LPTSTR,DWORD,BOOL,ACCESS_MASK))\r
10002                         GetProcAddress(nt->hUser32, "OpenDesktopA");\r
10003                 nt->CloseDesktop =\r
10004                         (BOOL (__stdcall *)(HDESK))\r
10005                         GetProcAddress(nt->hUser32, "CloseDesktop");\r
10006         }\r
10007 \r
10008         // デバッグ系 API\r
10009         if (nt->hDbgHelp != NULL)\r
10010         {\r
10011                 nt->MiniDumpWriteDump =\r
10012                         (BOOL (__stdcall *)(HANDLE,DWORD,HANDLE,MINIDUMP_TYPE,PMINIDUMP_EXCEPTION_INFORMATION,PMINIDUMP_USER_STREAM_INFORMATION,PMINIDUMP_CALLBACK_INFORMATION))\r
10013                         GetProcAddress(nt->hDbgHelp, "MiniDumpWriteDump");\r
10014         }\r
10015 \r
10016         return nt;\r
10017 }\r
10018 \r
10019 // NT 系関数の解放\r
10020 void MsFreeNtApiFunctions(NT_API *nt)\r
10021 {\r
10022         // 引数チェック\r
10023         if (nt == NULL)\r
10024         {\r
10025                 return;\r
10026         }\r
10027 \r
10028         if (nt->hSecur32 != NULL)\r
10029         {\r
10030                 FreeLibrary(nt->hSecur32);\r
10031         }\r
10032 \r
10033         if (nt->hNewDev != NULL)\r
10034         {\r
10035                 FreeLibrary(nt->hSetupApi);\r
10036                 FreeLibrary(nt->hNewDev);\r
10037         }\r
10038 \r
10039         FreeLibrary(nt->hAdvapi32);\r
10040 \r
10041         FreeLibrary(nt->hShell32);\r
10042 \r
10043         if (nt->hWtsApi32 != NULL)\r
10044         {\r
10045                 FreeLibrary(nt->hWtsApi32);\r
10046         }\r
10047 \r
10048         if (nt->hPsApi != NULL)\r
10049         {\r
10050                 FreeLibrary(nt->hPsApi);\r
10051         }\r
10052 \r
10053         if (nt->hUser32 != NULL)\r
10054         {\r
10055                 FreeLibrary(nt->hUser32);\r
10056         }\r
10057 \r
10058         if (nt->hDbgHelp != NULL)\r
10059         {\r
10060                 FreeLibrary(nt->hDbgHelp);\r
10061         }\r
10062 \r
10063         FreeLibrary(nt->hKernel32);\r
10064 \r
10065         Free(nt);\r
10066 }\r
10067 \r
10068 // 64 bit アプリケーションのために 32 bit レジストリキーへのアクセスを強制するアクセスマスクを生成する\r
10069 DWORD MsRegAccessMaskFor64Bit(bool force32bit)\r
10070 {\r
10071         return MsRegAccessMaskFor64BitEx(force32bit, false);\r
10072 }\r
10073 DWORD MsRegAccessMaskFor64BitEx(bool force32bit, bool force64bit)\r
10074 {\r
10075         if (MsIs64BitWindows() == false)\r
10076         {\r
10077                 return 0;\r
10078         }\r
10079         if (force32bit)\r
10080         {\r
10081                 return KEY_WOW64_32KEY;\r
10082         }\r
10083         if (force64bit)\r
10084         {\r
10085                 return KEY_WOW64_64KEY;\r
10086         }\r
10087 \r
10088         return 0;\r
10089 }\r
10090 \r
10091 // 値の削除\r
10092 bool MsRegDeleteValue(UINT root, char *keyname, char *valuename)\r
10093 {\r
10094         return MsRegDeleteValueEx(root, keyname, valuename, false);\r
10095 }\r
10096 bool MsRegDeleteValueEx(UINT root, char *keyname, char *valuename, bool force32bit)\r
10097 {\r
10098         return MsRegDeleteValueEx2(root, keyname, valuename, force32bit, false);\r
10099 }\r
10100 bool MsRegDeleteValueEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)\r
10101 {\r
10102         HKEY h;\r
10103         bool ret;\r
10104         // 引数チェック\r
10105         if (keyname == NULL)\r
10106         {\r
10107                 return false;\r
10108         }\r
10109 \r
10110         if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
10111         {\r
10112                 return false;\r
10113         }\r
10114 \r
10115         if (RegDeleteValue(h, valuename) != ERROR_SUCCESS)\r
10116         {\r
10117                 ret = false;\r
10118         }\r
10119         else\r
10120         {\r
10121                 ret = true;\r
10122         }\r
10123 \r
10124         RegCloseKey(h);\r
10125 \r
10126         return ret;\r
10127 }\r
10128 \r
10129 // キーの削除\r
10130 bool MsRegDeleteKey(UINT root, char *keyname)\r
10131 {\r
10132         return MsRegDeleteKeyEx(root, keyname, false);\r
10133 }\r
10134 bool MsRegDeleteKeyEx(UINT root, char *keyname, bool force32bit)\r
10135 {\r
10136         return MsRegDeleteKeyEx2(root, keyname, force32bit, false);\r
10137 }\r
10138 bool MsRegDeleteKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit)\r
10139 {\r
10140         // 引数チェック\r
10141         if (keyname == NULL)\r
10142         {\r
10143                 return false;\r
10144         }\r
10145 \r
10146         if (MsIsNt() && ms->nt->RegDeleteKeyExA != NULL)\r
10147         {\r
10148                 if (ms->nt->RegDeleteKeyExA(MsGetRootKeyFromInt(root), keyname, MsRegAccessMaskFor64BitEx(force32bit, force64bit), 0) != ERROR_SUCCESS)\r
10149                 {\r
10150                         return false;\r
10151                 }\r
10152         }\r
10153         else\r
10154         {\r
10155                 if (RegDeleteKey(MsGetRootKeyFromInt(root), keyname) != ERROR_SUCCESS)\r
10156                 {\r
10157                         return false;\r
10158                 }\r
10159         }\r
10160 \r
10161         return true;\r
10162 }\r
10163 \r
10164 // 値の列挙\r
10165 TOKEN_LIST *MsRegEnumValue(UINT root, char *keyname)\r
10166 {\r
10167         return MsRegEnumValueEx(root, keyname, false);\r
10168 }\r
10169 TOKEN_LIST *MsRegEnumValueEx(UINT root, char *keyname, bool force32bit)\r
10170 {\r
10171         return MsRegEnumValueEx2(root, keyname, force32bit, false);\r
10172 }\r
10173 TOKEN_LIST *MsRegEnumValueEx2(UINT root, char *keyname, bool force32bit, bool force64bit)\r
10174 {\r
10175         HKEY h;\r
10176         UINT i;\r
10177         TOKEN_LIST *t;\r
10178         LIST *o;\r
10179 \r
10180         if (keyname == NULL)\r
10181         {\r
10182                 h = MsGetRootKeyFromInt(root);\r
10183         }\r
10184         else\r
10185         {\r
10186                 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
10187                 {\r
10188                         return NULL;\r
10189                 }\r
10190         }\r
10191 \r
10192         o = NewListFast(CompareStr);\r
10193 \r
10194         for (i = 0;;i++)\r
10195         {\r
10196                 char tmp[MAX_SIZE];\r
10197                 UINT ret;\r
10198                 UINT size = sizeof(tmp);\r
10199 \r
10200                 Zero(tmp, sizeof(tmp));\r
10201                 ret = RegEnumValue(h, i, tmp, &size, NULL, NULL, NULL, NULL);\r
10202                 if (ret == ERROR_NO_MORE_ITEMS)\r
10203                 {\r
10204                         break;\r
10205                 }\r
10206                 else if (ret != ERROR_SUCCESS)\r
10207                 {\r
10208                         break;\r
10209                 }\r
10210 \r
10211                 Add(o, CopyStr(tmp));\r
10212         }\r
10213 \r
10214         Sort(o);\r
10215 \r
10216         t = ZeroMalloc(sizeof(TOKEN_LIST));\r
10217         t->NumTokens = LIST_NUM(o);\r
10218         t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);\r
10219         for (i = 0;i < t->NumTokens;i++)\r
10220         {\r
10221                 t->Token[i] = LIST_DATA(o, i);\r
10222         }\r
10223 \r
10224         ReleaseList(o);\r
10225 \r
10226         if (keyname != NULL)\r
10227         {\r
10228                 RegCloseKey(h);\r
10229         }\r
10230 \r
10231         return t;\r
10232 }\r
10233 \r
10234 // キーの列挙\r
10235 TOKEN_LIST *MsRegEnumKey(UINT root, char *keyname)\r
10236 {\r
10237         return MsRegEnumKeyEx(root, keyname, false);\r
10238 }\r
10239 TOKEN_LIST *MsRegEnumKeyEx(UINT root, char *keyname, bool force32bit)\r
10240 {\r
10241         return MsRegEnumKeyEx2(root, keyname, force32bit, false);\r
10242 }\r
10243 TOKEN_LIST *MsRegEnumKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit)\r
10244 {\r
10245         HKEY h;\r
10246         UINT i;\r
10247         TOKEN_LIST *t;\r
10248         LIST *o;\r
10249 \r
10250         if (keyname == NULL)\r
10251         {\r
10252                 h = MsGetRootKeyFromInt(root);\r
10253         }\r
10254         else\r
10255         {\r
10256                 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
10257                 {\r
10258                         return NULL;\r
10259                 }\r
10260         }\r
10261 \r
10262         o = NewListFast(CompareStr);\r
10263 \r
10264         for (i = 0;;i++)\r
10265         {\r
10266                 char tmp[MAX_SIZE];\r
10267                 UINT ret;\r
10268                 UINT size = sizeof(tmp);\r
10269                 FILETIME ft;\r
10270 \r
10271                 Zero(tmp, sizeof(tmp));\r
10272                 ret = RegEnumKeyEx(h, i, tmp, &size, NULL, NULL, NULL, &ft);\r
10273                 if (ret == ERROR_NO_MORE_ITEMS)\r
10274                 {\r
10275                         break;\r
10276                 }\r
10277                 else if (ret != ERROR_SUCCESS)\r
10278                 {\r
10279                         break;\r
10280                 }\r
10281 \r
10282                 Add(o, CopyStr(tmp));\r
10283         }\r
10284 \r
10285         Sort(o);\r
10286 \r
10287         t = ZeroMalloc(sizeof(TOKEN_LIST));\r
10288         t->NumTokens = LIST_NUM(o);\r
10289         t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);\r
10290         for (i = 0;i < t->NumTokens;i++)\r
10291         {\r
10292                 t->Token[i] = LIST_DATA(o, i);\r
10293         }\r
10294 \r
10295         ReleaseList(o);\r
10296 \r
10297         if (keyname != NULL)\r
10298         {\r
10299                 RegCloseKey(h);\r
10300         }\r
10301 \r
10302         return t;\r
10303 }\r
10304 \r
10305 // バイナリデータを設定する\r
10306 bool MsRegWriteBin(UINT root, char *keyname, char *valuename, void *data, UINT size)\r
10307 {\r
10308         return MsRegWriteBinEx(root, keyname, valuename, data, size, false);\r
10309 }\r
10310 bool MsRegWriteBinEx(UINT root, char *keyname, char *valuename, void *data, UINT size, bool force32bit)\r
10311 {\r
10312         return MsRegWriteBinEx2(root, keyname, valuename, data, size, force32bit, false);\r
10313 }\r
10314 bool MsRegWriteBinEx2(UINT root, char *keyname, char *valuename, void *data, UINT size, bool force32bit, bool force64bit)\r
10315 {\r
10316         // 引数チェック\r
10317         if (keyname == NULL || (size != 0 && data == NULL))\r
10318         {\r
10319                 return false;\r
10320         }\r
10321 \r
10322         return MsRegWriteValueEx2(root, keyname, valuename, REG_BINARY, data, size, force32bit, force64bit);\r
10323 }\r
10324 \r
10325 // 整数値を設定する\r
10326 bool MsRegWriteInt(UINT root, char *keyname, char *valuename, UINT value)\r
10327 {\r
10328         return MsRegWriteIntEx(root, keyname, valuename, value, false);\r
10329 }\r
10330 bool MsRegWriteIntEx(UINT root, char *keyname, char *valuename, UINT value, bool force32bit)\r
10331 {\r
10332         return MsRegWriteIntEx2(root, keyname, valuename, value, force32bit, false);\r
10333 }\r
10334 bool MsRegWriteIntEx2(UINT root, char *keyname, char *valuename, UINT value, bool force32bit, bool force64bit)\r
10335 {\r
10336         // 引数チェック\r
10337         if (keyname == NULL)\r
10338         {\r
10339                 return false;\r
10340         }\r
10341 \r
10342         // エンディアン補正\r
10343         if (IsBigEndian())\r
10344         {\r
10345                 value = Swap32(value);\r
10346         }\r
10347 \r
10348         return MsRegWriteValueEx2(root, keyname, valuename, REG_DWORD_LITTLE_ENDIAN, &value, sizeof(UINT), force32bit, force64bit);\r
10349 }\r
10350 \r
10351 // 文字列を設定する\r
10352 bool MsRegWriteStrExpand(UINT root, char *keyname, char *valuename, char *str)\r
10353 {\r
10354         return MsRegWriteStrExpandEx(root, keyname, valuename, str, false);\r
10355 }\r
10356 bool MsRegWriteStrExpandEx(UINT root, char *keyname, char *valuename, char *str, bool force32bit)\r
10357 {\r
10358         return MsRegWriteStrExpandEx2(root, keyname, valuename, str, force32bit, false);\r
10359 }\r
10360 bool MsRegWriteStrExpandEx2(UINT root, char *keyname, char *valuename, char *str, bool force32bit, bool force64bit)\r
10361 {\r
10362         // 引数チェック\r
10363         if (keyname == NULL || str == NULL)\r
10364         {\r
10365                 return false;\r
10366         }\r
10367 \r
10368         return MsRegWriteValueEx2(root, keyname, valuename, REG_EXPAND_SZ, str, StrSize(str), force32bit, force64bit);\r
10369 }\r
10370 bool MsRegWriteStrExpandW(UINT root, char *keyname, char *valuename, wchar_t *str)\r
10371 {\r
10372         return MsRegWriteStrExpandExW(root, keyname, valuename, str, false);\r
10373 }\r
10374 bool MsRegWriteStrExpandExW(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit)\r
10375 {\r
10376         return MsRegWriteStrExpandEx2W(root, keyname, valuename, str, force32bit, false);\r
10377 }\r
10378 bool MsRegWriteStrExpandEx2W(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit, bool force64bit)\r
10379 {\r
10380         // 引数チェック\r
10381         if (keyname == NULL || str == NULL)\r
10382         {\r
10383                 return false;\r
10384         }\r
10385 \r
10386         return MsRegWriteValueEx2W(root, keyname, valuename, REG_EXPAND_SZ, str, UniStrSize(str), force32bit, force64bit);\r
10387 }\r
10388 \r
10389 bool MsRegWriteStr(UINT root, char *keyname, char *valuename, char *str)\r
10390 {\r
10391         return MsRegWriteStrEx(root, keyname, valuename, str, false);\r
10392 }\r
10393 bool MsRegWriteStrEx(UINT root, char *keyname, char *valuename, char *str, bool force32bit)\r
10394 {\r
10395         return MsRegWriteStrEx2(root, keyname, valuename, str, force32bit, false);\r
10396 }\r
10397 bool MsRegWriteStrEx2(UINT root, char *keyname, char *valuename, char *str, bool force32bit, bool force64bit)\r
10398 {\r
10399         // 引数チェック\r
10400         if (keyname == NULL || str == NULL)\r
10401         {\r
10402                 return false;\r
10403         }\r
10404 \r
10405         return MsRegWriteValueEx2(root, keyname, valuename, REG_SZ, str, StrSize(str), force32bit, force64bit);\r
10406 }\r
10407 bool MsRegWriteStrW(UINT root, char *keyname, char *valuename, wchar_t *str)\r
10408 {\r
10409         return MsRegWriteStrExW(root, keyname, valuename, str, false);\r
10410 }\r
10411 bool MsRegWriteStrExW(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit)\r
10412 {\r
10413         return MsRegWriteStrEx2W(root, keyname, valuename, str, force32bit, false);\r
10414 }\r
10415 bool MsRegWriteStrEx2W(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit, bool force64bit)\r
10416 {\r
10417         // 引数チェック\r
10418         if (keyname == NULL || str == NULL)\r
10419         {\r
10420                 return false;\r
10421         }\r
10422 \r
10423         return MsRegWriteValueEx2W(root, keyname, valuename, REG_SZ, str, UniStrSize(str), force32bit, force64bit);\r
10424 }\r
10425 \r
10426 // 値を設定する\r
10427 bool MsRegWriteValue(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size)\r
10428 {\r
10429         return MsRegWriteValueEx(root, keyname, valuename, type, data, size, false);\r
10430 }\r
10431 bool MsRegWriteValueEx(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit)\r
10432 {\r
10433         return MsRegWriteValueEx2(root, keyname, valuename, type, data, size, force32bit, false);\r
10434 }\r
10435 bool MsRegWriteValueEx2(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit, bool force64bit)\r
10436 {\r
10437         HKEY h;\r
10438         // 引数チェック\r
10439         if (keyname == NULL || (size != 0 && data == NULL))\r
10440         {\r
10441                 return false;\r
10442         }\r
10443 \r
10444         // キーを作成する\r
10445         MsRegNewKeyEx2(root, keyname, force32bit, force64bit);\r
10446 \r
10447         // キーを開く\r
10448         if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
10449         {\r
10450                 return false;\r
10451         }\r
10452 \r
10453         // 値を書き込む\r
10454         if (RegSetValueEx(h, valuename, 0, type, data, size) != ERROR_SUCCESS)\r
10455         {\r
10456                 RegCloseKey(h);\r
10457                 return false;\r
10458         }\r
10459 \r
10460         // キーを閉じる\r
10461         RegCloseKey(h);\r
10462 \r
10463         return true;\r
10464 }\r
10465 bool MsRegWriteValueW(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size)\r
10466 {\r
10467         return MsRegWriteValueExW(root, keyname, valuename, type, data, size, false);\r
10468 }\r
10469 bool MsRegWriteValueExW(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit)\r
10470 {\r
10471         return MsRegWriteValueEx2W(root, keyname, valuename, type, data, size, force32bit, false);\r
10472 }\r
10473 bool MsRegWriteValueEx2W(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit, bool force64bit)\r
10474 {\r
10475         HKEY h;\r
10476         wchar_t valuename_w[MAX_SIZE];\r
10477         // 引数チェック\r
10478         if (keyname == NULL || (size != 0 && data == NULL))\r
10479         {\r
10480                 return false;\r
10481         }\r
10482 \r
10483         if (IsNt() == false)\r
10484         {\r
10485                 UINT size_a;\r
10486                 void *data_a;\r
10487                 bool ret;\r
10488 \r
10489                 if (type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ)\r
10490                 {\r
10491                         data_a = CopyUniToStr(data);\r
10492                         size_a = StrSize(data_a);\r
10493                 }\r
10494                 else\r
10495                 {\r
10496                         data_a = Clone(data, size);\r
10497                         size_a = size;\r
10498                 }\r
10499 \r
10500                 ret = MsRegWriteValueEx2(root, keyname, valuename, type, data_a, size_a, force32bit, force64bit);\r
10501 \r
10502                 Free(data_a);\r
10503 \r
10504                 return ret;\r
10505         }\r
10506 \r
10507         StrToUni(valuename_w, sizeof(valuename_w), valuename);\r
10508 \r
10509         // キーを作成する\r
10510         MsRegNewKeyEx2(root, keyname, force32bit, force64bit);\r
10511 \r
10512         // キーを開く\r
10513         if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
10514         {\r
10515                 return false;\r
10516         }\r
10517 \r
10518         // 値を書き込む\r
10519         if (RegSetValueExW(h, valuename_w, 0, type, data, size) != ERROR_SUCCESS)\r
10520         {\r
10521                 RegCloseKey(h);\r
10522                 return false;\r
10523         }\r
10524 \r
10525         // キーを閉じる\r
10526         RegCloseKey(h);\r
10527 \r
10528         return true;\r
10529 }\r
10530 \r
10531 // バイナリデータを取得する\r
10532 BUF *MsRegReadBin(UINT root, char *keyname, char *valuename)\r
10533 {\r
10534         return MsRegReadBinEx(root, keyname, valuename, false);\r
10535 }\r
10536 BUF *MsRegReadBinEx(UINT root, char *keyname, char *valuename, bool force32bit)\r
10537 {\r
10538         return MsRegReadBinEx2(root, keyname, valuename, force32bit, false);\r
10539 }\r
10540 BUF *MsRegReadBinEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)\r
10541 {\r
10542         char *ret;\r
10543         UINT type, size;\r
10544         BUF *b;\r
10545         // 引数チェック\r
10546         if (keyname == NULL || valuename == NULL)\r
10547         {\r
10548                 return 0;\r
10549         }\r
10550 \r
10551         // 値を読み込む\r
10552         if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)\r
10553         {\r
10554                 return 0;\r
10555         }\r
10556 \r
10557         b = NewBuf();\r
10558 \r
10559         WriteBuf(b, ret, size);\r
10560         SeekBuf(b, 0, 0);\r
10561 \r
10562         Free(ret);\r
10563 \r
10564         return b;\r
10565 }\r
10566 \r
10567 // 整数値を取得する\r
10568 UINT MsRegReadInt(UINT root, char *keyname, char *valuename)\r
10569 {\r
10570         return MsRegReadIntEx(root, keyname, valuename, false);\r
10571 }\r
10572 UINT MsRegReadIntEx(UINT root, char *keyname, char *valuename, bool force32bit)\r
10573 {\r
10574         return MsRegReadIntEx2(root, keyname, valuename, force32bit, false);\r
10575 }\r
10576 UINT MsRegReadIntEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)\r
10577 {\r
10578         char *ret;\r
10579         UINT type, size;\r
10580         UINT value;\r
10581         // 引数チェック\r
10582         if (keyname == NULL || valuename == NULL)\r
10583         {\r
10584                 return 0;\r
10585         }\r
10586 \r
10587         // 値を読み込む\r
10588         if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)\r
10589         {\r
10590                 return 0;\r
10591         }\r
10592 \r
10593         // 種類をチェックする\r
10594         if (type != REG_DWORD_LITTLE_ENDIAN && type != REG_DWORD_BIG_ENDIAN)\r
10595         {\r
10596                 // DWORD 以外である\r
10597                 Free(ret);\r
10598                 return 0;\r
10599         }\r
10600 \r
10601         // サイズをチェックする\r
10602         if (size != sizeof(UINT))\r
10603         {\r
10604                 Free(ret);\r
10605                 return 0;\r
10606         }\r
10607 \r
10608         Copy(&value, ret, sizeof(UINT));\r
10609 \r
10610         Free(ret);\r
10611 \r
10612         // エンディアン変換\r
10613         if (IsLittleEndian())\r
10614         {\r
10615 #ifdef  REG_DWORD_BIG_ENDIAN\r
10616                 if (type == REG_DWORD_BIG_ENDIAN)\r
10617                 {\r
10618                         value = Swap32(value);\r
10619                 }\r
10620 #endif  // REG_DWORD_BIG_ENDIAN\r
10621         }\r
10622         else\r
10623         {\r
10624 #ifdef  REG_DWORD_LITTLE_ENDIAN_FLAG\r
10625                 if (type == REG_DWORD_LITTLE_ENDIAN_FLAG)\r
10626                 {\r
10627                         value = Swap32(value);\r
10628                 }\r
10629 #endif  // REG_DWORD_LITTLE_ENDIAN_FLAG\r
10630         }\r
10631 \r
10632         return value;\r
10633 }\r
10634 \r
10635 // 文字列リストを取得する\r
10636 LIST *MsRegReadStrList(UINT root, char *keyname, char *valuename)\r
10637 {\r
10638         return MsRegReadStrListEx(root, keyname, valuename, false);\r
10639 }\r
10640 LIST *MsRegReadStrListEx(UINT root, char *keyname, char *valuename, bool force32bit)\r
10641 {\r
10642         return MsRegReadStrListEx2(root, keyname, valuename, force32bit, false);\r
10643 }\r
10644 LIST *MsRegReadStrListEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)\r
10645 {\r
10646         LIST *o;\r
10647         char *ret;\r
10648         UINT type, size;\r
10649         // 引数チェック\r
10650         if (keyname == NULL || valuename == NULL)\r
10651         {\r
10652                 return NULL;\r
10653         }\r
10654 \r
10655         // 値を読み込む\r
10656         if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)\r
10657         {\r
10658                 return NULL;\r
10659         }\r
10660 \r
10661         // 種類をチェックする\r
10662         if (type != REG_MULTI_SZ)\r
10663         {\r
10664                 // 文字列リスト以外である\r
10665                 Free(ret);\r
10666                 return NULL;\r
10667         }\r
10668 \r
10669         if (size < 2)\r
10670         {\r
10671                 // サイズ不正\r
10672                 Free(ret);\r
10673                 return NULL;\r
10674         }\r
10675 \r
10676         if (ret[size - 1] != 0)\r
10677         {\r
10678                 // データ不正\r
10679                 Free(ret);\r
10680                 return NULL;\r
10681         }\r
10682 \r
10683         // リスト作成\r
10684         o = StrToStrList(ret, size);\r
10685 \r
10686         Free(ret);\r
10687 \r
10688         return o;\r
10689 }\r
10690 \r
10691 // 文字列を取得する\r
10692 char *MsRegReadStr(UINT root, char *keyname, char *valuename)\r
10693 {\r
10694         return MsRegReadStrEx(root, keyname, valuename, false);\r
10695 }\r
10696 char *MsRegReadStrEx(UINT root, char *keyname, char *valuename, bool force32bit)\r
10697 {\r
10698         return MsRegReadStrEx2(root, keyname, valuename, force32bit, false);\r
10699 }\r
10700 char *MsRegReadStrEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)\r
10701 {\r
10702         char *ret;\r
10703         UINT type, size;\r
10704         // 引数チェック\r
10705         if (keyname == NULL || valuename == NULL)\r
10706         {\r
10707                 return NULL;\r
10708         }\r
10709 \r
10710         // 値を読み込む\r
10711         if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)\r
10712         {\r
10713                 return NULL;\r
10714         }\r
10715 \r
10716         // 種類をチェックする\r
10717         if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ)\r
10718         {\r
10719                 // 文字列以外である\r
10720                 Free(ret);\r
10721 \r
10722                 if (type == REG_MULTI_SZ)\r
10723                 {\r
10724                         // 文字列リストである\r
10725                         LIST *o = MsRegReadStrList(root, keyname, valuename);\r
10726                         if (o != NULL)\r
10727                         {\r
10728                                 if (LIST_NUM(o) >= 1)\r
10729                                 {\r
10730                                         ret = CopyStr(LIST_DATA(o, 0));\r
10731                                         FreeStrList(o);\r
10732                                         return ret;\r
10733                                 }\r
10734                         }\r
10735                 }\r
10736                 return NULL;\r
10737         }\r
10738 \r
10739         if (size == 0)\r
10740         {\r
10741                 // サイズ不正\r
10742                 Free(ret);\r
10743 \r
10744                 return CopyStr("");\r
10745         }\r
10746 \r
10747         if (ret[size - 1] != 0)\r
10748         {\r
10749                 // データ不正\r
10750                 Free(ret);\r
10751                 return NULL;\r
10752         }\r
10753 \r
10754         return ret;\r
10755 }\r
10756 wchar_t *MsRegReadStrW(UINT root, char *keyname, char *valuename)\r
10757 {\r
10758         return MsRegReadStrExW(root, keyname, valuename, false);\r
10759 }\r
10760 wchar_t *MsRegReadStrExW(UINT root, char *keyname, char *valuename, bool force32bit)\r
10761 {\r
10762         return MsRegReadStrEx2W(root, keyname, valuename, force32bit, false);\r
10763 }\r
10764 wchar_t *MsRegReadStrEx2W(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)\r
10765 {\r
10766         wchar_t *ret;\r
10767         UINT type, size;\r
10768         // 引数チェック\r
10769         if (keyname == NULL || valuename == NULL)\r
10770         {\r
10771                 return NULL;\r
10772         }\r
10773 \r
10774         // 値を読み込む\r
10775         if (MsRegReadValueEx2W(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)\r
10776         {\r
10777                 return NULL;\r
10778         }\r
10779 \r
10780         // 種類をチェックする\r
10781         if (type != REG_SZ && type != REG_EXPAND_SZ)\r
10782         {\r
10783                 // 文字列以外である\r
10784                 Free(ret);\r
10785 \r
10786                 return NULL;\r
10787         }\r
10788 \r
10789         if (ret[size / sizeof(wchar_t) - 1] != 0)\r
10790         {\r
10791                 // データ不正\r
10792                 Free(ret);\r
10793                 return NULL;\r
10794         }\r
10795 \r
10796         return ret;\r
10797 }\r
10798 \r
10799 // 値を読み込む\r
10800 bool MsRegReadValue(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size)\r
10801 {\r
10802         return MsRegReadValueEx(root, keyname, valuename, data, type, size, false);\r
10803 }\r
10804 bool MsRegReadValueEx(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit)\r
10805 {\r
10806         return MsRegReadValueEx2(root, keyname, valuename, data, type, size, force32bit, false);\r
10807 }\r
10808 bool MsRegReadValueEx2(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit, bool force64bit)\r
10809 {\r
10810         HKEY h;\r
10811         UINT ret;\r
10812         // 引数チェック\r
10813         if (keyname == NULL || data == NULL || type == NULL || size == NULL)\r
10814         {\r
10815                 return false;\r
10816         }\r
10817         *type = 0;\r
10818         *size = 0;\r
10819 \r
10820         // キーを開く\r
10821         if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
10822         {\r
10823                 return false;\r
10824         }\r
10825 \r
10826         // 値を開く\r
10827         *data = ZeroMalloc(*size);\r
10828         ret = RegQueryValueEx(h, valuename, 0, type, *data, size);\r
10829 \r
10830         if (ret == ERROR_SUCCESS)\r
10831         {\r
10832                 // 読み取り完了\r
10833                 RegCloseKey(h);\r
10834                 return true;\r
10835         }\r
10836 \r
10837         if (ret != ERROR_MORE_DATA)\r
10838         {\r
10839                 // 変なエラーが発生した\r
10840                 Free(*data);\r
10841                 *data = NULL;\r
10842                 RegCloseKey(h);\r
10843                 return false;\r
10844         }\r
10845 \r
10846         // メモリを再確保してデータを取得\r
10847         *data = ReAlloc(*data, *size);\r
10848         ret = RegQueryValueEx(h, valuename, 0, type, *data, size);\r
10849         if (ret != ERROR_SUCCESS)\r
10850         {\r
10851                 // エラー発生\r
10852                 Free(*data);\r
10853                 *data = NULL;\r
10854                 RegCloseKey(h);\r
10855         }\r
10856 \r
10857         RegCloseKey(h);\r
10858 \r
10859         return true;\r
10860 }\r
10861 bool MsRegReadValueW(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size)\r
10862 {\r
10863         return MsRegReadValueExW(root, keyname, valuename, data, type, size, false);\r
10864 }\r
10865 bool MsRegReadValueExW(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit)\r
10866 {\r
10867         return MsRegReadValueEx2W(root, keyname, valuename, data, type, size, force32bit, false);\r
10868 }\r
10869 bool MsRegReadValueEx2W(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit, bool force64bit)\r
10870 {\r
10871         HKEY h;\r
10872         UINT ret;\r
10873         wchar_t valuename_w[MAX_SIZE];\r
10874         // 引数チェック\r
10875         if (keyname == NULL || data == NULL || type == NULL || size == NULL)\r
10876         {\r
10877                 return false;\r
10878         }\r
10879         *type = 0;\r
10880         *size = 0;\r
10881 \r
10882         if (IsNt() == false)\r
10883         {\r
10884                 bool ret;\r
10885                 void *data_a = NULL;\r
10886                 UINT type_a = 0, size_a = 0;\r
10887 \r
10888                 ret = MsRegReadValueEx2(root, keyname, valuename, &data_a, &type_a, &size_a, force32bit, force64bit);\r
10889 \r
10890                 if (ret != false)\r
10891                 {\r
10892                         if (type_a == REG_SZ || type_a == REG_MULTI_SZ || type_a == REG_EXPAND_SZ)\r
10893                         {\r
10894                                 *data = CopyStrToUni(data_a);\r
10895                                 Free(data_a);\r
10896 \r
10897                                 size_a = UniStrSize(*data);\r
10898                         }\r
10899                         else\r
10900                         {\r
10901                                 *data = data_a;\r
10902                         }\r
10903 \r
10904                         *type = type_a;\r
10905                         *size = size_a;\r
10906                 }\r
10907 \r
10908                 return ret;\r
10909         }\r
10910 \r
10911         StrToUni(valuename_w, sizeof(valuename_w), valuename);\r
10912 \r
10913         // キーを開く\r
10914         if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
10915         {\r
10916                 return false;\r
10917         }\r
10918 \r
10919         // 値を開く\r
10920         *data = ZeroMalloc(*size);\r
10921         ret = RegQueryValueExW(h, valuename_w, 0, type, *data, size);\r
10922 \r
10923         if (ret == ERROR_SUCCESS)\r
10924         {\r
10925                 // 読み取り完了\r
10926                 RegCloseKey(h);\r
10927                 return true;\r
10928         }\r
10929 \r
10930         if (ret != ERROR_MORE_DATA)\r
10931         {\r
10932                 // 変なエラーが発生した\r
10933                 Free(*data);\r
10934                 *data = NULL;\r
10935                 RegCloseKey(h);\r
10936                 return false;\r
10937         }\r
10938 \r
10939         // メモリを再確保してデータを取得\r
10940         *data = ReAlloc(*data, *size);\r
10941         ret = RegQueryValueExW(h, valuename_w, 0, type, *data, size);\r
10942         if (ret != ERROR_SUCCESS)\r
10943         {\r
10944                 // エラー発生\r
10945                 Free(*data);\r
10946                 *data = NULL;\r
10947                 RegCloseKey(h);\r
10948         }\r
10949 \r
10950         RegCloseKey(h);\r
10951 \r
10952         return true;\r
10953 }\r
10954 \r
10955 // 値の種類とサイズを取得する\r
10956 bool MsRegGetValueTypeAndSize(UINT root, char *keyname, char *valuename, UINT *type, UINT *size)\r
10957 {\r
10958         return MsRegGetValueTypeAndSizeEx(root, keyname, valuename, type, size, false);\r
10959 }\r
10960 bool MsRegGetValueTypeAndSizeEx(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit)\r
10961 {\r
10962         return MsRegGetValueTypeAndSizeEx2(root, keyname, valuename, type, size, force32bit, false);\r
10963 }\r
10964 bool MsRegGetValueTypeAndSizeEx2(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit, bool force64bit)\r
10965 {\r
10966         HKEY h;\r
10967         UINT ret;\r
10968         // 引数チェック\r
10969         if (keyname == NULL)\r
10970         {\r
10971                 return false;\r
10972         }\r
10973         if (type != NULL)\r
10974         {\r
10975                 *type = 0;\r
10976         }\r
10977         if (size != NULL)\r
10978         {\r
10979                 *size = 0;\r
10980         }\r
10981 \r
10982         // キーを開く\r
10983         if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
10984         {\r
10985                 return false;\r
10986         }\r
10987 \r
10988         // 値を開く\r
10989         ret = RegQueryValueEx(h, valuename, 0, type, NULL, size);\r
10990 \r
10991         if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)\r
10992         {\r
10993                 RegCloseKey(h);\r
10994                 return true;\r
10995         }\r
10996 \r
10997         RegCloseKey(h);\r
10998 \r
10999         return false;\r
11000 }\r
11001 bool MsRegGetValueTypeAndSizeW(UINT root, char *keyname, char *valuename, UINT *type, UINT *size)\r
11002 {\r
11003         return MsRegGetValueTypeAndSizeExW(root, keyname, valuename, type, size, false);\r
11004 }\r
11005 bool MsRegGetValueTypeAndSizeExW(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit)\r
11006 {\r
11007         return MsRegGetValueTypeAndSizeEx2W(root, keyname, valuename, type, size, force32bit, false);\r
11008 }\r
11009 bool MsRegGetValueTypeAndSizeEx2W(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit, bool force64bit)\r
11010 {\r
11011         HKEY h;\r
11012         UINT ret;\r
11013         wchar_t valuename_w[MAX_SIZE];\r
11014         // 引数チェック\r
11015         if (keyname == NULL)\r
11016         {\r
11017                 return false;\r
11018         }\r
11019         if (type != NULL)\r
11020         {\r
11021                 *type = 0;\r
11022         }\r
11023         if (size != NULL)\r
11024         {\r
11025                 *size = 0;\r
11026         }\r
11027         if (IsNt() == false)\r
11028         {\r
11029                 UINT type_a = 0;\r
11030                 UINT size_a = 0;\r
11031 \r
11032                 bool ret = MsRegGetValueTypeAndSizeEx2(root, keyname, valuename, &type_a, &size_a, force32bit, force64bit);\r
11033 \r
11034                 if (type_a == REG_SZ || type_a == REG_MULTI_SZ || type_a == REG_EXPAND_SZ)\r
11035                 {\r
11036                         size_a = size_a * sizeof(wchar_t);\r
11037                 }\r
11038 \r
11039                 if (type != NULL)\r
11040                 {\r
11041                         *type = type_a;\r
11042                 }\r
11043 \r
11044                 if (size != NULL)\r
11045                 {\r
11046                         *size = size_a;\r
11047                 }\r
11048 \r
11049                 return ret;\r
11050         }\r
11051 \r
11052         StrToUni(valuename_w, sizeof(valuename_w), valuename);\r
11053 \r
11054         // キーを開く\r
11055         if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
11056         {\r
11057                 return false;\r
11058         }\r
11059 \r
11060         // 値を開く\r
11061         ret = RegQueryValueExW(h, valuename_w, 0, type, NULL, size);\r
11062 \r
11063         if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)\r
11064         {\r
11065                 RegCloseKey(h);\r
11066                 return true;\r
11067         }\r
11068 \r
11069         RegCloseKey(h);\r
11070 \r
11071         return false;\r
11072 }\r
11073 \r
11074 // 指定された値がレジストリに存在するかどうか確認する\r
11075 bool MsRegIsValue(UINT root, char *keyname, char *valuename)\r
11076 {\r
11077         return MsRegIsValueEx(root, keyname, valuename, false);\r
11078 }\r
11079 bool MsRegIsValueEx(UINT root, char *keyname, char *valuename, bool force32bit)\r
11080 {\r
11081         return MsRegIsValueEx2(root, keyname, valuename, force32bit, false);\r
11082 }\r
11083 bool MsRegIsValueEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)\r
11084 {\r
11085         HKEY h;\r
11086         UINT type, size;\r
11087         UINT ret;\r
11088         // 引数チェック\r
11089         if (keyname == NULL)\r
11090         {\r
11091                 return false;\r
11092         }\r
11093 \r
11094         // キーを開く\r
11095         if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
11096         {\r
11097                 return false;\r
11098         }\r
11099 \r
11100         // 値を開く\r
11101         size = 0;\r
11102         ret = RegQueryValueEx(h, valuename, 0, &type, NULL, &size);\r
11103 \r
11104         if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)\r
11105         {\r
11106                 RegCloseKey(h);\r
11107                 return true;\r
11108         }\r
11109 \r
11110         RegCloseKey(h);\r
11111 \r
11112         return false;\r
11113 }\r
11114 \r
11115 // レジストリにキーを作成する\r
11116 bool MsRegNewKey(UINT root, char *keyname)\r
11117 {\r
11118         return MsRegNewKeyEx(root, keyname, false);\r
11119 }\r
11120 bool MsRegNewKeyEx(UINT root, char *keyname, bool force32bit)\r
11121 {\r
11122         return MsRegNewKeyEx2(root, keyname, force32bit, false);\r
11123 }\r
11124 bool MsRegNewKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit)\r
11125 {\r
11126         HKEY h;\r
11127         // 引数チェック\r
11128         if (keyname == NULL)\r
11129         {\r
11130                 return false;\r
11131         }\r
11132 \r
11133         // キーが存在するかどうか確認する\r
11134         if (MsRegIsKeyEx2(root, keyname, force32bit, force64bit))\r
11135         {\r
11136                 // すでに存在している\r
11137                 return true;\r
11138         }\r
11139 \r
11140         // キーを作成する\r
11141         if (RegCreateKeyEx(MsGetRootKeyFromInt(root), keyname, 0, NULL, REG_OPTION_NON_VOLATILE,\r
11142                 KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), NULL, &h, NULL) != ERROR_SUCCESS)\r
11143         {\r
11144                 // 失敗\r
11145                 return false;\r
11146         }\r
11147 \r
11148         RegCloseKey(h);\r
11149 \r
11150         return true;\r
11151 }\r
11152 \r
11153 // 指定されたキーがレジストリに存在するかどうか確認する\r
11154 bool MsRegIsKey(UINT root, char *name)\r
11155 {\r
11156         return MsRegIsKeyEx(root, name, false);\r
11157 }\r
11158 bool MsRegIsKeyEx(UINT root, char *name, bool force32bit)\r
11159 {\r
11160         return MsRegIsKeyEx2(root, name, force32bit, false);\r
11161 }\r
11162 bool MsRegIsKeyEx2(UINT root, char *name, bool force32bit, bool force64bit)\r
11163 {\r
11164         HKEY h;\r
11165         // 引数チェック\r
11166         if (name == NULL)\r
11167         {\r
11168                 return false;\r
11169         }\r
11170 \r
11171         if (RegOpenKeyEx(MsGetRootKeyFromInt(root), name, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)\r
11172         {\r
11173                 return false;\r
11174         }\r
11175 \r
11176         RegCloseKey(h);\r
11177 \r
11178         return true;\r
11179 }\r
11180 \r
11181 // ルートキーハンドルの取得\r
11182 HKEY MsGetRootKeyFromInt(UINT root)\r
11183 {\r
11184         switch (root)\r
11185         {\r
11186         case REG_CLASSES_ROOT:\r
11187                 return HKEY_CLASSES_ROOT;\r
11188 \r
11189         case REG_LOCAL_MACHINE:\r
11190                 return HKEY_LOCAL_MACHINE;\r
11191 \r
11192         case REG_CURRENT_USER:\r
11193                 return HKEY_CURRENT_USER;\r
11194 \r
11195         case REG_USERS:\r
11196                 return HKEY_USERS;\r
11197         }\r
11198 \r
11199         return NULL;\r
11200 }\r
11201 \r
11202 // コマンドライン文字列から実行ファイル名の部分をカットする (Unicode 版)\r
11203 wchar_t *MsCutExeNameFromUniCommandLine(wchar_t *str)\r
11204 {\r
11205         // 引数チェック\r
11206         if (str == NULL)\r
11207         {\r
11208                 return NULL;\r
11209         }\r
11210 \r
11211         if (str[0] != L'\"')\r
11212         {\r
11213                 UINT i = UniSearchStrEx(str, L" ", 0, true);\r
11214                 if (i == INFINITE)\r
11215                 {\r
11216                         return str + UniStrLen(str);\r
11217                 }\r
11218                 else\r
11219                 {\r
11220                         return str + i + 1;\r
11221                 }\r
11222         }\r
11223         else\r
11224         {\r
11225                 str++;\r
11226                 while (true)\r
11227                 {\r
11228                         if ((*str) == 0)\r
11229                         {\r
11230                                 return str + UniStrLen(str);\r
11231                         }\r
11232                         if ((*str) == L'\"')\r
11233                         {\r
11234                                 break;\r
11235                         }\r
11236                         str++;\r
11237                 }\r
11238 \r
11239                 while (true)\r
11240                 {\r
11241                         if ((*str) == 0)\r
11242                         {\r
11243                                 return str + UniStrLen(str);\r
11244                         }\r
11245                         if ((*str) == L' ')\r
11246                         {\r
11247                                 return str + 1;\r
11248                         }\r
11249                         str++;\r
11250                 }\r
11251         }\r
11252 }\r
11253 \r
11254 // コマンドライン文字列から実行ファイル名の部分をカットする\r
11255 char *MsCutExeNameFromCommandLine(char *str)\r
11256 {\r
11257         // 引数チェック\r
11258         if (str == NULL)\r
11259         {\r
11260                 return NULL;\r
11261         }\r
11262 \r
11263         if (str[0] != '\"')\r
11264         {\r
11265                 UINT i = SearchStrEx(str, " ", 0, true);\r
11266                 if (i == INFINITE)\r
11267                 {\r
11268                         return str + StrLen(str);\r
11269                 }\r
11270                 else\r
11271                 {\r
11272                         return str + i + 1;\r
11273                 }\r
11274         }\r
11275         else\r
11276         {\r
11277                 str++;\r
11278                 while (true)\r
11279                 {\r
11280                         if ((*str) == 0)\r
11281                         {\r
11282                                 return str + StrLen(str);\r
11283                         }\r
11284                         if ((*str) == '\"')\r
11285                         {\r
11286                                 break;\r
11287                         }\r
11288                         str++;\r
11289                 }\r
11290 \r
11291                 while (true)\r
11292                 {\r
11293                         if ((*str) == 0)\r
11294                         {\r
11295                                 return str + StrLen(str);\r
11296                         }\r
11297                         if ((*str) == ' ')\r
11298                         {\r
11299                                 return str + 1;\r
11300                         }\r
11301                         str++;\r
11302                 }\r
11303         }\r
11304 }\r
11305 \r
11306 // プロセスハンドルの取得\r
11307 void *MsGetCurrentProcess()\r
11308 {\r
11309         return ms->hCurrentProcess;\r
11310 }\r
11311 \r
11312 // プロセス ID の取得\r
11313 UINT MsGetCurrentProcessId()\r
11314 {\r
11315         return ms->CurrentProcessId;\r
11316 }\r
11317 \r
11318 // EXE ファイル名の取得\r
11319 char *MsGetExeFileName()\r
11320 {\r
11321         return ms == NULL ? "Unknown" : ms->ExeFileName;\r
11322 }\r
11323 \r
11324 // EXE ファイルが置いてあるディレクトリ名の取得\r
11325 char *MsGetExeDirName()\r
11326 {\r
11327         return ms->ExeFileDir;\r
11328 }\r
11329 wchar_t *MsGetExeDirNameW()\r
11330 {\r
11331         return ms->ExeFileDirW;\r
11332 }\r
11333 \r
11334 // 特殊なディレクトリ名の取得\r
11335 char *MsGetSpecialDir(int id)\r
11336 {\r
11337         LPITEMIDLIST t = NULL;\r
11338         char tmp[MAX_PATH];\r
11339 \r
11340         if (SHGetSpecialFolderLocation(NULL, id, &t) != S_OK)\r
11341         {\r
11342                 return CopyStr(ms->ExeFileDir);\r
11343         }\r
11344 \r
11345         if (SHGetPathFromIDList(t, tmp) == false)\r
11346         {\r
11347                 return CopyStr(ms->ExeFileDir);\r
11348         }\r
11349 \r
11350         Win32NukuEn(tmp, sizeof(tmp), tmp);\r
11351 \r
11352         return CopyStr(tmp);\r
11353 }\r
11354 wchar_t *MsGetSpecialDirW(int id)\r
11355 {\r
11356         LPITEMIDLIST t = NULL;\r
11357         wchar_t tmp[MAX_PATH];\r
11358 \r
11359         if (IsNt() == false)\r
11360         {\r
11361                 char *tmp = MsGetSpecialDir(id);\r
11362                 wchar_t *ret = CopyStrToUni(tmp);\r
11363 \r
11364                 Free(tmp);\r
11365 \r
11366                 return ret;\r
11367         }\r
11368 \r
11369         if (SHGetSpecialFolderLocation(NULL, id, &t) != S_OK)\r
11370         {\r
11371                 return UniCopyStr(ms->ExeFileDirW);\r
11372         }\r
11373 \r
11374         if (SHGetPathFromIDListW(t, tmp) == false)\r
11375         {\r
11376                 return UniCopyStr(ms->ExeFileDirW);\r
11377         }\r
11378 \r
11379         Win32NukuEnW(tmp, sizeof(tmp), tmp);\r
11380 \r
11381         return UniCopyStr(tmp);\r
11382 }\r
11383 \r
11384 // 特殊なディレクトリをすべて取得する\r
11385 void MsGetSpecialDirs()\r
11386 {\r
11387         char tmp[MAX_PATH];\r
11388 \r
11389         // System32\r
11390         GetSystemDirectory(tmp, sizeof(tmp));\r
11391         Win32NukuEn(tmp, sizeof(tmp), tmp);\r
11392         ms->System32Dir = CopyStr(tmp);\r
11393         ms->System32DirW = CopyStrToUni(tmp);\r
11394 \r
11395         // Windows ディレクトリは System32 ディレクトリの 1 つ上にある\r
11396         Win32GetDirFromPath(tmp, sizeof(tmp), tmp);\r
11397         Win32NukuEn(tmp, sizeof(tmp), tmp);\r
11398         ms->WindowsDir = CopyStr(tmp);\r
11399         ms->WindowsDirW = CopyStrToUni(tmp);\r
11400 \r
11401         // Windows ディレクトリの下の Temp ディレクトリ\r
11402         Format(tmp, sizeof(tmp), "%s\\Temp", ms->WindowsDir);\r
11403         ms->WinTempDir = CopyStr(tmp);\r
11404         ms->WinTempDirW = CopyStrToUni(tmp);\r
11405         MsUniMakeDirEx(ms->WinTempDirW);\r
11406 \r
11407         // システムドライブ\r
11408         tmp[2] = 0;\r
11409         ms->WindowsDrive = CopyStr(tmp);\r
11410         ms->WindowsDriveW = CopyStrToUni(tmp);\r
11411 \r
11412         // Temp\r
11413         GetTempPath(MAX_PATH, tmp);\r
11414         Win32NukuEn(tmp, sizeof(tmp), tmp);\r
11415         ms->TempDir = CopyStr(tmp);\r
11416 \r
11417         // Temp (Unicode) の取得\r
11418         if (IsNt())\r
11419         {\r
11420                 wchar_t tmp_w[MAX_PATH];\r
11421 \r
11422                 GetTempPathW(MAX_PATH, tmp_w);\r
11423                 Win32NukuEnW(tmp_w, sizeof(tmp_w), tmp_w);\r
11424 \r
11425                 ms->TempDirW = CopyUniStr(tmp_w);\r
11426         }\r
11427         else\r
11428         {\r
11429                 ms->TempDirW = CopyStrToUni(tmp);\r
11430         }\r
11431         MakeDirExW(ms->TempDirW);\r
11432         MakeDirEx(ms->TempDir);\r
11433 \r
11434         // Program Files\r
11435         ms->ProgramFilesDir = MsGetSpecialDir(CSIDL_PROGRAM_FILES);\r
11436         if (StrCmpi(ms->ProgramFilesDir, ms->ExeFileDir) == 0)\r
11437         {\r
11438                 char tmp[MAX_PATH];\r
11439                 Format(tmp, sizeof(tmp), "%s\\Program Files", ms->WindowsDrive);\r
11440 \r
11441                 Free(ms->ProgramFilesDir);\r
11442                 ms->ProgramFilesDir = CopyStr(tmp);\r
11443         }\r
11444 \r
11445         ms->ProgramFilesDirW = MsGetSpecialDirW(CSIDL_PROGRAM_FILES);\r
11446         if (UniStrCmpi(ms->ProgramFilesDirW, ms->ExeFileDirW) == 0)\r
11447         {\r
11448                 wchar_t tmp[MAX_PATH];\r
11449                 UniFormat(tmp, sizeof(tmp), L"%s\\Program Files", ms->WindowsDriveW);\r
11450 \r
11451                 Free(ms->ProgramFilesDirW);\r
11452                 ms->ProgramFilesDirW = UniCopyStr(tmp);\r
11453         }\r
11454 \r
11455         if (MsIsNt())\r
11456         {\r
11457                 // 共通のスタートメニュー\r
11458                 ms->CommonStartMenuDir = MsGetSpecialDir(CSIDL_COMMON_STARTMENU);\r
11459                 ms->CommonStartMenuDirW = MsGetSpecialDirW(CSIDL_COMMON_STARTMENU);\r
11460 \r
11461                 // 共通のプログラム\r
11462                 ms->CommonProgramsDir = MsGetSpecialDir(CSIDL_COMMON_PROGRAMS);\r
11463                 ms->CommonProgramsDirW = MsGetSpecialDirW(CSIDL_COMMON_PROGRAMS);\r
11464 \r
11465                 // 共通のスタートアップ\r
11466                 ms->CommonStartupDir = MsGetSpecialDir(CSIDL_COMMON_STARTUP);\r
11467                 ms->CommonStartupDirW = MsGetSpecialDirW(CSIDL_COMMON_STARTUP);\r
11468 \r
11469                 // 共通のアプリケーションデータ\r
11470                 ms->CommonAppDataDir = MsGetSpecialDir(CSIDL_COMMON_APPDATA);\r
11471                 ms->CommonAppDataDirW = MsGetSpecialDirW(CSIDL_COMMON_APPDATA);\r
11472 \r
11473                 // 共通のデスクトップ\r
11474                 ms->CommonDesktopDir = MsGetSpecialDir(CSIDL_COMMON_DESKTOPDIRECTORY);\r
11475                 ms->CommonDesktopDirW = MsGetSpecialDirW(CSIDL_COMMON_DESKTOPDIRECTORY);\r
11476 \r
11477                 // Local Settings\r
11478                 ms->LocalAppDataDir = MsGetSpecialDir(CSIDL_LOCAL_APPDATA);\r
11479                 ms->LocalAppDataDirW = MsGetSpecialDirW(CSIDL_LOCAL_APPDATA);\r
11480         }\r
11481         else\r
11482         {\r
11483                 // 個別のスタートメニュー\r
11484                 ms->PersonalStartMenuDir = MsGetSpecialDir(CSIDL_STARTMENU);\r
11485                 ms->CommonStartMenuDir = CopyStr(ms->PersonalStartMenuDir);\r
11486                 ms->PersonalStartMenuDirW = MsGetSpecialDirW(CSIDL_STARTMENU);\r
11487                 ms->CommonStartMenuDirW = CopyUniStr(ms->PersonalStartMenuDirW);\r
11488 \r
11489                 // 個別のプログラム\r
11490                 ms->PersonalProgramsDir = MsGetSpecialDir(CSIDL_PROGRAMS);\r
11491                 ms->CommonProgramsDir = CopyStr(ms->PersonalProgramsDir);\r
11492                 ms->PersonalProgramsDirW = MsGetSpecialDirW(CSIDL_PROGRAMS);\r
11493                 ms->CommonProgramsDirW = CopyUniStr(ms->PersonalProgramsDirW);\r
11494 \r
11495                 // 個別のスタートアップ\r
11496                 ms->PersonalStartupDir = MsGetSpecialDir(CSIDL_STARTUP);\r
11497                 ms->CommonStartupDir = CopyStr(ms->PersonalStartupDir);\r
11498                 ms->PersonalStartupDirW = MsGetSpecialDirW(CSIDL_STARTUP);\r
11499                 ms->CommonStartupDirW = CopyUniStr(ms->PersonalStartupDirW);\r
11500 \r
11501                 // 個別のアプリケーションデータ\r
11502                 ms->PersonalAppDataDir = MsGetSpecialDir(CSIDL_APPDATA);\r
11503                 ms->CommonAppDataDir = CopyStr(ms->PersonalAppDataDir);\r
11504                 ms->PersonalAppDataDirW = MsGetSpecialDirW(CSIDL_APPDATA);\r
11505                 ms->CommonAppDataDirW = CopyUniStr(ms->PersonalAppDataDirW);\r
11506 \r
11507                 // 個別のデスクトップ\r
11508                 ms->PersonalDesktopDir = MsGetSpecialDir(CSIDL_DESKTOP);\r
11509                 ms->CommonDesktopDir = CopyStr(ms->PersonalDesktopDir);\r
11510                 ms->PersonalDesktopDirW = MsGetSpecialDirW(CSIDL_DESKTOP);\r
11511                 ms->CommonDesktopDirW = CopyUniStr(ms->PersonalDesktopDirW);\r
11512 \r
11513                 // Local Settings\r
11514                 ms->LocalAppDataDir = CopyStr(ms->PersonalAppDataDir);\r
11515                 ms->LocalAppDataDirW = CopyUniStr(ms->PersonalAppDataDirW);\r
11516         }\r
11517 }\r
11518 \r
11519 // 現在のユーザーが Administrators かどうかチェックする\r
11520 bool MsCheckIsAdmin()\r
11521 {\r
11522         UCHAR test_bit[32];\r
11523         UCHAR tmp[32];\r
11524         char *name = "Vpn_Check_Admin_Key";\r
11525         DWORD type;\r
11526         DWORD size;\r
11527         Rand(test_bit, sizeof(test_bit));\r
11528 \r
11529         if (RegSetValueEx(HKEY_LOCAL_MACHINE, name, 0, REG_BINARY, test_bit, sizeof(test_bit)) != ERROR_SUCCESS)\r
11530         {\r
11531                 return false;\r
11532         }\r
11533 \r
11534         size = sizeof(tmp);\r
11535         if (RegQueryValueEx(HKEY_LOCAL_MACHINE, name, 0, &type, tmp, &size) != ERROR_SUCCESS)\r
11536         {\r
11537                 return false;\r
11538         }\r
11539 \r
11540         RegDeleteValue(HKEY_LOCAL_MACHINE, name);\r
11541 \r
11542         if (Cmp(test_bit, tmp, 32) != 0)\r
11543         {\r
11544                 return false;\r
11545         }\r
11546 \r
11547         return true;\r
11548 }\r
11549 \r
11550 // ライブラリの初期化\r
11551 void MsInit()\r
11552 {\r
11553         char *str_ansi;\r
11554         wchar_t *str_unicode;\r
11555         OSVERSIONINFO os;\r
11556         char tmp[MAX_SIZE];\r
11557         UINT size;\r
11558         if (ms != NULL)\r
11559         {\r
11560                 // すでに初期化されている\r
11561                 return;\r
11562         }\r
11563 \r
11564         ms = ZeroMalloc(sizeof(MS));\r
11565 \r
11566         // インスタンスハンドルの取得\r
11567         ms->hInst = GetModuleHandleA(NULL);\r
11568 \r
11569         // KERNEL32.DLL の取得\r
11570         ms->hKernel32 = LoadLibrary("kernel32.dll");\r
11571 \r
11572         // OS からコマンドライン文字列を取得する\r
11573         str_ansi = CopyStr(GetCommandLineA());\r
11574         Trim(str_ansi);\r
11575         str_unicode = UniCopyStr(GetCommandLineW());\r
11576         UniTrim(str_unicode);\r
11577 \r
11578         SetCommandLineStr(MsCutExeNameFromCommandLine(str_ansi));\r
11579         SetCommandLineUniStr(MsCutExeNameFromUniCommandLine(str_unicode));\r
11580 \r
11581         Free(str_unicode);\r
11582         Free(str_ansi);\r
11583 \r
11584         // OS のバージョンを取得する\r
11585         Zero(&os, sizeof(os));\r
11586         os.dwOSVersionInfoSize = sizeof(os);\r
11587         GetVersionEx(&os);\r
11588 \r
11589         if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)\r
11590         {\r
11591                 // NT 系\r
11592                 ms->IsNt = true;\r
11593 \r
11594                 ms->nt = MsLoadNtApiFunctions();\r
11595 \r
11596                 if (ms->nt == NULL)\r
11597                 {\r
11598                         ms->IsNt = false;\r
11599                         ms->IsAdmin = true;\r
11600                 }\r
11601                 else\r
11602                 {\r
11603                         // Administrators 判定\r
11604                         ms->IsAdmin = MsCheckIsAdmin();\r
11605                 }\r
11606         }\r
11607         else\r
11608         {\r
11609                 // 9x 系: 常に Administrators を偽装\r
11610                 ms->IsAdmin = true;\r
11611         }\r
11612 \r
11613         // 現在のプロセスに関する情報を取得する\r
11614         ms->hCurrentProcess = GetCurrentProcess();\r
11615         ms->CurrentProcessId = GetCurrentProcessId();\r
11616 \r
11617         // EXE ファイル名を取得\r
11618         GetModuleFileName(NULL, tmp, sizeof(tmp));\r
11619         ms->ExeFileName = CopyStr(tmp);\r
11620         Win32GetDirFromPath(tmp, sizeof(tmp), tmp);\r
11621         ms->ExeFileDir = CopyStr(tmp);\r
11622 \r
11623         // EXE ファイル名 (Unicode) を取得\r
11624         if (IsNt())\r
11625         {\r
11626                 wchar_t tmp_w[MAX_PATH];\r
11627 \r
11628                 GetModuleFileNameW(NULL, tmp_w, sizeof(tmp_w));\r
11629                 ms->ExeFileNameW = CopyUniStr(tmp_w);\r
11630 \r
11631                 Win32GetDirFromPathW(tmp_w, sizeof(tmp_w), tmp_w);\r
11632                 ms->ExeFileDirW = CopyUniStr(tmp_w);\r
11633         }\r
11634         else\r
11635         {\r
11636                 ms->ExeFileNameW = CopyStrToUni(ms->ExeFileName);\r
11637                 ms->ExeFileDirW = CopyStrToUni(ms->ExeFileDir);\r
11638         }\r
11639 \r
11640         // 特殊なディレクトリを取得\r
11641         MsGetSpecialDirs();\r
11642 \r
11643         // 一時ディレクトリの初期化\r
11644         MsInitTempDir();\r
11645 \r
11646         // ユーザー名の取得\r
11647         size = sizeof(tmp);\r
11648         GetUserName(tmp, &size);\r
11649         ms->UserName = CopyStr(tmp);\r
11650 \r
11651         // ユーザー名の取得 (Unicode)\r
11652         if (IsNt())\r
11653         {\r
11654                 wchar_t tmp_w[MAX_PATH];\r
11655 \r
11656                 size = sizeof(tmp_w);\r
11657 \r
11658                 GetUserNameW(tmp_w, &size);\r
11659                 ms->UserNameW = CopyUniStr(tmp_w);\r
11660         }\r
11661         else\r
11662         {\r
11663                 ms->UserNameW = CopyStrToUni(ms->UserName);\r
11664         }\r
11665 \r
11666         // フルユーザー名の取得\r
11667         if (ms->nt != NULL && ms->nt->GetUserNameExA != NULL)\r
11668         {\r
11669                 wchar_t tmp_w[MAX_PATH];\r
11670 \r
11671                 size = sizeof(tmp);\r
11672                 if (ms->nt->GetUserNameExA(NameSamCompatible, tmp, &size))\r
11673                 {\r
11674                         ms->UserNameEx = CopyStr(tmp);\r
11675                 }\r
11676 \r
11677                 size = sizeof(tmp_w);\r
11678                 if (ms->nt->GetUserNameExW(NameSamCompatible, tmp_w, &size))\r
11679                 {\r
11680                         ms->UserNameExW = CopyUniStr(tmp_w);\r
11681                 }\r
11682         }\r
11683 \r
11684         if (ms->UserNameEx == NULL)\r
11685         {\r
11686                 ms->UserNameEx = CopyStr(ms->UserName);\r
11687         }\r
11688         if (ms->UserNameExW == NULL)\r
11689         {\r
11690                 ms->UserNameExW = CopyUniStr(ms->UserNameW);\r
11691         }\r
11692 \r
11693         ms_critical_section = ZeroMalloc(sizeof(CRITICAL_SECTION));\r
11694         InitializeCriticalSection(ms_critical_section);\r
11695 \r
11696         // アダプタリストの初期化\r
11697         MsInitAdapterListModule();\r
11698 \r
11699         // minidump ベースファイル名の初期化\r
11700         if (true)\r
11701         {\r
11702                 wchar_t tmp[MAX_PATH];\r
11703                 if (MsIsAdmin())\r
11704                 {\r
11705                         CombinePathW(tmp, sizeof(tmp), ms->ExeFileDirW, L"vpn_debug\\dump");\r
11706                 }\r
11707                 else\r
11708                 {\r
11709                         CombinePathW(tmp, sizeof(tmp), ms->TempDirW, L"vpn_debug\\dump");\r
11710                 }\r
11711                 ms->MinidumpBaseFileNameW = CopyUniStr(tmp);\r
11712         }\r
11713 \r
11714         MsSetEnableMinidump(true);\r
11715 \r
11716         if (MsIsNt())\r
11717         {\r
11718                 if (ms->nt->MiniDumpWriteDump != NULL)\r
11719                 {\r
11720                         SetUnhandledExceptionFilter(MsExceptionHandler);\r
11721                 }\r
11722         }\r
11723 }\r
11724 \r
11725 // minidump を作成するかどうか選択する\r
11726 void MsSetEnableMinidump(bool enabled)\r
11727 {\r
11728         ms->MiniDumpEnabled = enabled;\r
11729 }\r
11730 \r
11731 // minidump を出力する\r
11732 void MsWriteMinidump(wchar_t *filename, void *ex)\r
11733 {\r
11734         wchar_t tmp[MAX_PATH];\r
11735         wchar_t dir[MAX_PATH];\r
11736         HANDLE h;\r
11737         MINIDUMP_EXCEPTION_INFORMATION info;\r
11738         struct _EXCEPTION_POINTERS *exp = (struct _EXCEPTION_POINTERS *)ex;\r
11739 \r
11740         if (filename != NULL)\r
11741         {\r
11742                 UniStrCpy(tmp, sizeof(tmp), filename);\r
11743         }\r
11744         else\r
11745         {\r
11746                 SYSTEMTIME tm;\r
11747 \r
11748                 Zero(&tm, sizeof(tm));\r
11749                 GetLocalTime(&tm);\r
11750 \r
11751                 UniFormat(tmp, sizeof(tmp), L"%s_%04u%02u%02u_%02u%02u%02u.dmp",\r
11752                         ms->MinidumpBaseFileNameW,\r
11753                         tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond);\r
11754         }\r
11755 \r
11756         GetDirNameFromFilePathW(dir, sizeof(dir), tmp);\r
11757 \r
11758         CreateDirectoryW(dir, NULL);\r
11759 \r
11760         Zero(&info, sizeof(info));\r
11761 \r
11762         if (exp != NULL)\r
11763         {\r
11764                 info.ThreadId = GetCurrentThreadId();\r
11765                 info.ExceptionPointers = exp;\r
11766                 info.ClientPointers = true;\r
11767         }\r
11768 \r
11769         h = CreateFileW(tmp, GENERIC_READ | GENERIC_WRITE,\r
11770                 FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,\r
11771                 NULL);\r
11772         if (h != INVALID_HANDLE_VALUE)\r
11773         {\r
11774                 ms->nt->MiniDumpWriteDump(ms->hCurrentProcess, ms->CurrentProcessId,\r
11775                         h,\r
11776                         MiniDumpNormal | MiniDumpWithFullMemory | MiniDumpWithDataSegs |\r
11777                         MiniDumpWithHandleData\r
11778                         ,\r
11779                         info.ThreadId == 0 ? NULL : &info, NULL, NULL);\r
11780 \r
11781                 FlushFileBuffers(h);\r
11782                 CloseHandle(h);\r
11783         }\r
11784 }\r
11785 \r
11786 // 例外ハンドラ\r
11787 LONG CALLBACK MsExceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)\r
11788 {\r
11789         if (ms->MiniDumpEnabled)\r
11790         {\r
11791                 MsWriteMinidump(NULL, ExceptionInfo);\r
11792         }\r
11793 \r
11794         return EXCEPTION_CONTINUE_SEARCH;\r
11795 }\r
11796 \r
11797 // ライブラリの解放\r
11798 void MsFree()\r
11799 {\r
11800         if (ms == NULL)\r
11801         {\r
11802                 // 初期化されていない\r
11803                 return;\r
11804         }\r
11805 \r
11806         // アダプタリストの解放\r
11807         MsFreeAdapterListModule();\r
11808 \r
11809         // 一時ディレクトリの解放\r
11810         MsFreeTempDir();\r
11811 \r
11812         if (ms->IsNt)\r
11813         {\r
11814                 // NT 系 API の解放\r
11815                 MsFreeNtApiFunctions(ms->nt);\r
11816         }\r
11817 \r
11818         // メモリ解放\r
11819         // ANSI\r
11820         Free(ms->WindowsDir);\r
11821         Free(ms->System32Dir);\r
11822         Free(ms->TempDir);\r
11823         Free(ms->WinTempDir);\r
11824         Free(ms->WindowsDrive);\r
11825         Free(ms->ProgramFilesDir);\r
11826         Free(ms->CommonStartMenuDir);\r
11827         Free(ms->CommonProgramsDir);\r
11828         Free(ms->CommonStartupDir);\r
11829         Free(ms->CommonAppDataDir);\r
11830         Free(ms->CommonDesktopDir);\r
11831         Free(ms->PersonalStartMenuDir);\r
11832         Free(ms->PersonalProgramsDir);\r
11833         Free(ms->PersonalStartupDir);\r
11834         Free(ms->PersonalAppDataDir);\r
11835         Free(ms->PersonalDesktopDir);\r
11836         Free(ms->MyDocumentsDir);\r
11837         Free(ms->ExeFileDir);\r
11838         Free(ms->ExeFileName);\r
11839         Free(ms->UserName);\r
11840         Free(ms->UserNameEx);\r
11841         Free(ms->LocalAppDataDir);\r
11842         // Unicode\r
11843         Free(ms->WindowsDirW);\r
11844         Free(ms->System32DirW);\r
11845         Free(ms->TempDirW);\r
11846         Free(ms->WinTempDirW);\r
11847         Free(ms->WindowsDriveW);\r
11848         Free(ms->ProgramFilesDirW);\r
11849         Free(ms->CommonStartMenuDirW);\r
11850         Free(ms->CommonProgramsDirW);\r
11851         Free(ms->CommonStartupDirW);\r
11852         Free(ms->CommonAppDataDirW);\r
11853         Free(ms->CommonDesktopDirW);\r
11854         Free(ms->PersonalStartMenuDirW);\r
11855         Free(ms->PersonalProgramsDirW);\r
11856         Free(ms->PersonalStartupDirW);\r
11857         Free(ms->PersonalAppDataDirW);\r
11858         Free(ms->PersonalDesktopDirW);\r
11859         Free(ms->MyDocumentsDirW);\r
11860         Free(ms->ExeFileDirW);\r
11861         Free(ms->ExeFileNameW);\r
11862         Free(ms->UserNameW);\r
11863         Free(ms->UserNameExW);\r
11864         Free(ms->LocalAppDataDirW);\r
11865         Free(ms->MinidumpBaseFileNameW);\r
11866         Free(ms);\r
11867         ms = NULL;\r
11868 \r
11869         Free(ms_critical_section);\r
11870         ms_critical_section = NULL;\r
11871 }\r
11872 \r
11873 // ディレクトリ取得関係\r
11874 char *MsGetCommonAppDataDir()\r
11875 {\r
11876         return ms->CommonAppDataDir;\r
11877 }\r
11878 char *MsGetLocalAppDataDir()\r
11879 {\r
11880         return ms->LocalAppDataDir;\r
11881 }\r
11882 char *MsGetWindowsDir()\r
11883 {\r
11884         return ms->WindowsDir;\r
11885 }\r
11886 wchar_t *MsGetWindowsDirW()\r
11887 {\r
11888         return ms->WindowsDirW;\r
11889 }\r
11890 char *MsGetSystem32Dir()\r
11891 {\r
11892         return ms->System32Dir;\r
11893 }\r
11894 char *MsGetTempDir()\r
11895 {\r
11896         return ms->TempDir;\r
11897 }\r
11898 char *MsGetWindowsDrive()\r
11899 {\r
11900         return ms->WindowsDrive;\r
11901 }\r
11902 char *MsGetProgramFilesDir()\r
11903 {\r
11904         return ms->ProgramFilesDir;\r
11905 }\r
11906 char *MsGetCommonStartMenuDir()\r
11907 {\r
11908         return ms->CommonStartMenuDir;\r
11909 }\r
11910 char *MsGetCommonProgramsDir()\r
11911 {\r
11912         return ms->CommonProgramsDir;\r
11913 }\r
11914 char *MsGetCommonStartupDir()\r
11915 {\r
11916         return ms->CommonStartupDir;\r
11917 }\r
11918 char *MsGetCommonDesktopDir()\r
11919 {\r
11920         return ms->CommonDesktopDir;\r
11921 }\r
11922 char *MsGetPersonalStartMenuDir()\r
11923 {\r
11924         if (ms->PersonalStartMenuDir == NULL)\r
11925         {\r
11926                 ms->PersonalStartMenuDir = MsGetSpecialDir(CSIDL_STARTMENU);\r
11927         }\r
11928         return ms->PersonalStartMenuDir;\r
11929 }\r
11930 char *MsGetPersonalProgramsDir()\r
11931 {\r
11932         if (ms->PersonalProgramsDir == NULL)\r
11933         {\r
11934                 ms->PersonalProgramsDir = MsGetSpecialDir(CSIDL_PROGRAMS);\r
11935         }\r
11936         return ms->PersonalProgramsDir;\r
11937 }\r
11938 char *MsGetPersonalStartupDir()\r
11939 {\r
11940         if (ms->PersonalStartupDir == NULL)\r
11941         {\r
11942                 ms->PersonalStartupDir = MsGetSpecialDir(CSIDL_STARTUP);\r
11943         }\r
11944         return ms->PersonalStartupDir;\r
11945 }\r
11946 char *MsGetPersonalAppDataDir()\r
11947 {\r
11948         if (ms->PersonalAppDataDir == NULL)\r
11949         {\r
11950                 ms->PersonalAppDataDir = MsGetSpecialDir(CSIDL_APPDATA);\r
11951         }\r
11952         return ms->PersonalAppDataDir;\r
11953 }\r
11954 char *MsGetPersonalDesktopDir()\r
11955 {\r
11956         if (ms->PersonalDesktopDir == NULL)\r
11957         {\r
11958                 ms->PersonalDesktopDir = MsGetSpecialDir(CSIDL_DESKTOP);\r
11959         }\r
11960         return ms->PersonalDesktopDir;\r
11961 }\r
11962 char *MsGetMyDocumentsDir()\r
11963 {\r
11964         if (ms->MyDocumentsDir == NULL)\r
11965         {\r
11966                 ms->MyDocumentsDir = MsGetSpecialDir(CSIDL_PERSONAL);\r
11967         }\r
11968         return ms->MyDocumentsDir;\r
11969 }\r
11970 char *MsGetMyTempDir()\r
11971 {\r
11972         return ms->MyTempDir;\r
11973 }\r
11974 char *MsGetUserName()\r
11975 {\r
11976         return ms->UserName;\r
11977 }\r
11978 char *MsGetUserNameEx()\r
11979 {\r
11980         return ms->UserNameEx;\r
11981 }\r
11982 char *MsGetWinTempDir()\r
11983 {\r
11984         return ms->WinTempDir;\r
11985 }\r
11986 \r
11987 wchar_t *MsGetExeFileNameW()\r
11988 {\r
11989         return ms == NULL ? L"Unknown" : ms->ExeFileNameW;\r
11990 }\r
11991 wchar_t *MsGetExeFileDirW()\r
11992 {\r
11993         return ms->ExeFileDirW;\r
11994 }\r
11995 wchar_t *MsGetWindowDirW()\r
11996 {\r
11997         return ms->WindowsDirW;\r
11998 }\r
11999 wchar_t *MsGetSystem32DirW()\r
12000 {\r
12001         return ms->System32DirW;\r
12002 }\r
12003 wchar_t *MsGetTempDirW()\r
12004 {\r
12005         return ms->TempDirW;\r
12006 }\r
12007 wchar_t *MsGetWindowsDriveW()\r
12008 {\r
12009         return ms->WindowsDriveW;\r
12010 }\r
12011 wchar_t *MsGetProgramFilesDirW()\r
12012 {\r
12013         return ms->ProgramFilesDirW;\r
12014 }\r
12015 wchar_t *MsGetCommonStartMenuDirW()\r
12016 {\r
12017         return ms->CommonStartMenuDirW;\r
12018 }\r
12019 wchar_t *MsGetCommonProgramsDirW()\r
12020 {\r
12021         return ms->CommonProgramsDirW;\r
12022 }\r
12023 wchar_t *MsGetCommonStartupDirW()\r
12024 {\r
12025         return ms->CommonStartupDirW;\r
12026 }\r
12027 wchar_t *MsGetCommonAppDataDirW()\r
12028 {\r
12029         return ms->CommonAppDataDirW;\r
12030 }\r
12031 wchar_t *MsGetCommonDesktopDirW()\r
12032 {\r
12033         return ms->CommonDesktopDirW;\r
12034 }\r
12035 wchar_t *MsGetPersonalStartMenuDirW()\r
12036 {\r
12037         if (ms->PersonalStartMenuDirW == NULL)\r
12038         {\r
12039                 ms->PersonalStartMenuDirW = MsGetSpecialDirW(CSIDL_STARTMENU);\r
12040         }\r
12041 \r
12042         return ms->PersonalStartMenuDirW;\r
12043 }\r
12044 wchar_t *MsGetPersonalProgramsDirW()\r
12045 {\r
12046         if (ms->PersonalProgramsDirW == NULL)\r
12047         {\r
12048                 ms->PersonalProgramsDirW = MsGetSpecialDirW(CSIDL_PROGRAMS);\r
12049         }\r
12050 \r
12051         return ms->PersonalProgramsDirW;\r
12052 }\r
12053 wchar_t *MsGetPersonalStartupDirW()\r
12054 {\r
12055         if (ms->PersonalStartupDirW == NULL)\r
12056         {\r
12057                 ms->PersonalStartupDirW = MsGetSpecialDirW(CSIDL_STARTUP);\r
12058         }\r
12059 \r
12060         return ms->PersonalStartupDirW;\r
12061 }\r
12062 wchar_t *MsGetPersonalAppDataDirW()\r
12063 {\r
12064         if (ms->PersonalAppDataDirW == NULL)\r
12065         {\r
12066                 ms->PersonalAppDataDirW = MsGetSpecialDirW(CSIDL_APPDATA);\r
12067         }\r
12068 \r
12069         return ms->PersonalAppDataDirW;\r
12070 }\r
12071 wchar_t *MsGetPersonalDesktopDirW()\r
12072 {\r
12073         if (ms->PersonalDesktopDirW == NULL)\r
12074         {\r
12075                 ms->PersonalDesktopDirW = MsGetSpecialDirW(CSIDL_DESKTOP);\r
12076         }\r
12077 \r
12078         return ms->PersonalDesktopDirW;\r
12079 }\r
12080 wchar_t *MsGetMyDocumentsDirW()\r
12081 {\r
12082         if (ms->MyDocumentsDirW == NULL)\r
12083         {\r
12084                 ms->MyDocumentsDirW = MsGetSpecialDirW(CSIDL_PERSONAL);\r
12085         }\r
12086 \r
12087         return ms->MyDocumentsDirW;\r
12088 }\r
12089 wchar_t *MsGetLocalAppDataDirW()\r
12090 {\r
12091         return ms->LocalAppDataDirW;\r
12092 }\r
12093 wchar_t *MsGetMyTempDirW()\r
12094 {\r
12095         return ms->MyTempDirW;\r
12096 }\r
12097 wchar_t *MsGetUserNameW()\r
12098 {\r
12099         return ms->UserNameW;\r
12100 }\r
12101 wchar_t *MsGetUserNameExW()\r
12102 {\r
12103         return ms->UserNameExW;\r
12104 }\r
12105 wchar_t *MsGetWinTempDirW()\r
12106 {\r
12107         return ms->WinTempDirW;\r
12108 }\r
12109 \r
12110 \r
12111 #endif  // WIN32\r
12112 \r