syswin.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2008 by Florian Klaempfl and Pavel Ozerski
  4. member of the Free Pascal development team.
  5. FPC Pascal system unit part shared by win32/win64.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {
  13. Error code definitions for the Win32 API functions
  14. Values are 32 bit values layed out as follows:
  15. 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
  16. 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  17. +---+-+-+-----------------------+-------------------------------+
  18. |Sev|C|R| Facility | Code |
  19. +---+-+-+-----------------------+-------------------------------+
  20. where
  21. Sev - is the severity code
  22. 00 - Success
  23. 01 - Informational
  24. 10 - Warning
  25. 11 - Error
  26. C - is the Customer code flag
  27. R - is a reserved bit
  28. Facility - is the facility code
  29. Code - is the facility's status code
  30. }
  31. const
  32. SEVERITY_SUCCESS = $00000000;
  33. SEVERITY_INFORMATIONAL = $40000000;
  34. SEVERITY_WARNING = $80000000;
  35. SEVERITY_ERROR = $C0000000;
  36. const
  37. STATUS_SEGMENT_NOTIFICATION = $40000005;
  38. DBG_TERMINATE_THREAD = $40010003;
  39. DBG_TERMINATE_PROCESS = $40010004;
  40. DBG_CONTROL_C = $40010005;
  41. DBG_CONTROL_BREAK = $40010008;
  42. STATUS_GUARD_PAGE_VIOLATION = $80000001;
  43. STATUS_DATATYPE_MISALIGNMENT = $80000002;
  44. STATUS_BREAKPOINT = $80000003;
  45. STATUS_SINGLE_STEP = $80000004;
  46. DBG_EXCEPTION_NOT_HANDLED = $80010001;
  47. STATUS_ACCESS_VIOLATION = $C0000005;
  48. STATUS_IN_PAGE_ERROR = $C0000006;
  49. STATUS_INVALID_HANDLE = $C0000008;
  50. STATUS_NO_MEMORY = $C0000017;
  51. STATUS_ILLEGAL_INSTRUCTION = $C000001D;
  52. STATUS_NONCONTINUABLE_EXCEPTION = $C0000025;
  53. STATUS_INVALID_DISPOSITION = $C0000026;
  54. STATUS_ARRAY_BOUNDS_EXCEEDED = $C000008C;
  55. STATUS_FLOAT_DENORMAL_OPERAND = $C000008D;
  56. STATUS_FLOAT_DIVIDE_BY_ZERO = $C000008E;
  57. STATUS_FLOAT_INEXACT_RESULT = $C000008F;
  58. STATUS_FLOAT_INVALID_OPERATION = $C0000090;
  59. STATUS_FLOAT_OVERFLOW = $C0000091;
  60. STATUS_FLOAT_STACK_CHECK = $C0000092;
  61. STATUS_FLOAT_UNDERFLOW = $C0000093;
  62. STATUS_INTEGER_DIVIDE_BY_ZERO = $C0000094;
  63. STATUS_INTEGER_OVERFLOW = $C0000095;
  64. STATUS_PRIVILEGED_INSTRUCTION = $C0000096;
  65. STATUS_STACK_OVERFLOW = $C00000FD;
  66. STATUS_CONTROL_C_EXIT = $C000013A;
  67. STATUS_FLOAT_MULTIPLE_FAULTS = $C00002B4;
  68. STATUS_FLOAT_MULTIPLE_TRAPS = $C00002B5;
  69. STATUS_REG_NAT_CONSUMPTION = $C00002C9;
  70. EXCEPTION_EXECUTE_HANDLER = 1;
  71. EXCEPTION_CONTINUE_EXECUTION = -1;
  72. EXCEPTION_CONTINUE_SEARCH = 0;
  73. CONTEXT_X86 = $00010000;
  74. CONTEXT_CONTROL = CONTEXT_X86 or $00000001;
  75. CONTEXT_INTEGER = CONTEXT_X86 or $00000002;
  76. CONTEXT_SEGMENTS = CONTEXT_X86 or $00000004;
  77. CONTEXT_FLOATING_POINT = CONTEXT_X86 or $00000008;
  78. CONTEXT_DEBUG_REGISTERS = CONTEXT_X86 or $00000010;
  79. CONTEXT_EXTENDED_REGISTERS = CONTEXT_X86 or $00000020;
  80. CONTEXT_FULL = CONTEXT_CONTROL or CONTEXT_INTEGER or CONTEXT_SEGMENTS;
  81. MAXIMUM_SUPPORTED_EXTENSION = 512;
  82. {*****************************************************************************
  83. Parameter Handling
  84. *****************************************************************************}
  85. procedure setup_arguments;
  86. var
  87. arglen,
  88. count : longint;
  89. argstart,
  90. pc,arg : pchar;
  91. quote : Boolean;
  92. argvlen : longint;
  93. buf: array[0..259] of char; // need MAX_PATH bytes, not 256!
  94. procedure allocarg(idx,len:longint);
  95. var
  96. oldargvlen : longint;
  97. begin
  98. if idx>=argvlen then
  99. begin
  100. oldargvlen:=argvlen;
  101. argvlen:=(idx+8) and (not 7);
  102. sysreallocmem(argv,argvlen*sizeof(pointer));
  103. fillchar(argv[oldargvlen],(argvlen-oldargvlen)*sizeof(pointer),0);
  104. end;
  105. { use realloc to reuse already existing memory }
  106. { always allocate, even if length is zero, since }
  107. { the arg. is still present! }
  108. sysreallocmem(argv[idx],len+1);
  109. end;
  110. begin
  111. { create commandline, it starts with the executed filename which is argv[0] }
  112. { Win32 passes the command NOT via the args, but via getmodulefilename}
  113. count:=0;
  114. argv:=nil;
  115. argvlen:=0;
  116. ArgLen := GetModuleFileName(0, @buf[0], sizeof(buf));
  117. buf[ArgLen] := #0; // be safe
  118. allocarg(0,arglen);
  119. move(buf,argv[0]^,arglen+1);
  120. { Setup cmdline variable }
  121. cmdline:=GetCommandLine;
  122. { process arguments }
  123. pc:=cmdline;
  124. {$IfDef SYSTEM_DEBUG_STARTUP}
  125. Writeln(stderr,'Win32 GetCommandLine is #',pc,'#');
  126. {$EndIf }
  127. while pc^<>#0 do
  128. begin
  129. { skip leading spaces }
  130. while pc^ in [#1..#32] do
  131. inc(pc);
  132. if pc^=#0 then
  133. break;
  134. { calc argument length }
  135. quote:=False;
  136. argstart:=pc;
  137. arglen:=0;
  138. while (pc^<>#0) do
  139. begin
  140. case pc^ of
  141. #1..#32 :
  142. begin
  143. if quote then
  144. inc(arglen)
  145. else
  146. break;
  147. end;
  148. '"' :
  149. if pc[1]<>'"' then
  150. quote := not quote
  151. else
  152. inc(pc);
  153. else
  154. inc(arglen);
  155. end;
  156. inc(pc);
  157. end;
  158. { copy argument }
  159. { Don't copy the first one, it is already there.}
  160. If Count<>0 then
  161. begin
  162. allocarg(count,arglen);
  163. quote:=False;
  164. pc:=argstart;
  165. arg:=argv[count];
  166. while (pc^<>#0) do
  167. begin
  168. case pc^ of
  169. #1..#32 :
  170. begin
  171. if quote then
  172. begin
  173. arg^:=pc^;
  174. inc(arg);
  175. end
  176. else
  177. break;
  178. end;
  179. '"' :
  180. if pc[1]<>'"' then
  181. quote := not quote
  182. else
  183. inc(pc);
  184. else
  185. begin
  186. arg^:=pc^;
  187. inc(arg);
  188. end;
  189. end;
  190. inc(pc);
  191. end;
  192. arg^:=#0;
  193. end;
  194. {$IfDef SYSTEM_DEBUG_STARTUP}
  195. Writeln(stderr,'dos arg ',count,' #',arglen,'#',argv[count],'#');
  196. {$EndIf SYSTEM_DEBUG_STARTUP}
  197. inc(count);
  198. end;
  199. { get argc }
  200. argc:=count;
  201. { free unused memory, leaving a nil entry at the end }
  202. sysreallocmem(argv,(count+1)*sizeof(pointer));
  203. argv[count] := nil;
  204. end;
  205. function paramcount : longint;
  206. begin
  207. paramcount := argc - 1;
  208. end;
  209. {$ifdef xFPC_UNICODE_RTL}
  210. function paramstr(l : longint) : unicodestring;
  211. {$else}
  212. function paramstr(l : longint) : rawbytestring;
  213. {$endif}
  214. begin
  215. if (l>=0) and (l<argc) then
  216. {$ifdef FPC_UNICODE_RTL}
  217. paramstr:=(argv[l])
  218. {$else}
  219. paramstr:=argv[l]
  220. {$endif}
  221. else
  222. paramstr:='';
  223. end;
  224. procedure randomize;
  225. begin
  226. randseed:=GetTickCount;
  227. end;
  228. Var
  229. DLLInitState : Longint = -1;
  230. DLLBuf : Jmp_buf;
  231. function Dll_entry{$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}(const info : TEntryInformation){$endif FPC_HAS_INDIRECT_MAIN_INFORMATION} : longbool; [public,alias:'_FPC_DLL_Entry'];
  232. begin
  233. {$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}
  234. EntryInformation:=info;
  235. {$endif FPC_HAS_INDIRECT_MAIN_INFORMATION}
  236. IsLibrary:=true;
  237. DllInitState:=DLLreason;
  238. Dll_entry:=false; { return value is ignored, except when DLLreason=DLL_PROCESS_ATTACH }
  239. case DLLreason of
  240. DLL_PROCESS_ATTACH :
  241. begin
  242. MainThreadIdWin32 := Win32GetCurrentThreadId;
  243. If SetJmp(DLLBuf) = 0 then
  244. begin
  245. {$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}
  246. EntryInformation.PascalMain();
  247. {$else FPC_HAS_INDIRECT_MAIN_INFORMATION}
  248. PascalMain;
  249. {$endif FPC_HAS_INDIRECT_MAIN_INFORMATION}
  250. Dll_entry:=true;
  251. end
  252. else
  253. Dll_entry:=(ExitCode=0);
  254. end;
  255. DLL_THREAD_ATTACH :
  256. begin
  257. { SysInitMultithreading must not be called here,
  258. see comments in exec_tls_callback below }
  259. { Allocate Threadvars }
  260. SysAllocateThreadVars;
  261. { NS : no idea what is correct to pass here - pass dummy value for now }
  262. { passing a dummy is ok, the correct value is read from the coff header of SysInstance (FK) }
  263. InitThread($1000000); { Assume everything is idempotent there, as the thread could have been created with BeginThread... }
  264. if assigned(Dll_Thread_Attach_Hook) then
  265. Dll_Thread_Attach_Hook(DllParam);
  266. end;
  267. DLL_THREAD_DETACH :
  268. begin
  269. if assigned(Dll_Thread_Detach_Hook) then
  270. Dll_Thread_Detach_Hook(DllParam);
  271. { Release Threadvars }
  272. if TlsGetValue(TLSKey)<>nil then
  273. DoneThread; { Assume everything is idempotent there }
  274. end;
  275. DLL_PROCESS_DETACH :
  276. begin
  277. if MainThreadIDWin32=0 then // already been here.
  278. exit;
  279. If SetJmp(DLLBuf) = 0 then
  280. begin
  281. if assigned(Dll_Process_Detach_Hook) then
  282. Dll_Process_Detach_Hook(DllParam);
  283. InternalExit;
  284. end;
  285. SysReleaseThreadVars;
  286. { Free TLS resources used by ThreadVars }
  287. SysFiniMultiThreading;
  288. MainThreadIDWin32:=0;
  289. end;
  290. end;
  291. DllInitState:=-1;
  292. end;
  293. {****************************************************************************
  294. Error Message writing using messageboxes
  295. ****************************************************************************}
  296. function MessageBox(w1:longint;l1,l2:pointer;w2:longint):longint;
  297. stdcall;external 'user32' name 'MessageBoxA';
  298. const
  299. ErrorBufferLength = 1024;
  300. var
  301. ErrorBuf : array[0..ErrorBufferLength] of char;
  302. ErrorLen : SizeInt;
  303. Function ErrorWrite(Var F: TextRec): Integer;
  304. {
  305. An error message should always end with #13#10#13#10
  306. }
  307. var
  308. i : SizeInt;
  309. Begin
  310. while F.BufPos>0 do
  311. begin
  312. begin
  313. if F.BufPos+ErrorLen>ErrorBufferLength then
  314. i:=ErrorBufferLength-ErrorLen
  315. else
  316. i:=F.BufPos;
  317. Move(F.BufPtr^,ErrorBuf[ErrorLen],i);
  318. inc(ErrorLen,i);
  319. ErrorBuf[ErrorLen]:=#0;
  320. end;
  321. if ErrorLen=ErrorBufferLength then
  322. begin
  323. MessageBox(0,@ErrorBuf,pchar('Error'),0);
  324. ErrorLen:=0;
  325. end;
  326. Dec(F.BufPos,i);
  327. end;
  328. ErrorWrite:=0;
  329. End;
  330. Function ErrorClose(Var F: TextRec): Integer;
  331. begin
  332. if ErrorLen>0 then
  333. begin
  334. MessageBox(0,@ErrorBuf,pchar('Error'),0);
  335. ErrorLen:=0;
  336. end;
  337. ErrorLen:=0;
  338. ErrorClose:=0;
  339. end;
  340. Function ErrorOpen(Var F: TextRec): Integer;
  341. Begin
  342. TextRec(F).InOutFunc:=@ErrorWrite;
  343. TextRec(F).FlushFunc:=@ErrorWrite;
  344. TextRec(F).CloseFunc:=@ErrorClose;
  345. ErrorLen:=0;
  346. ErrorOpen:=0;
  347. End;
  348. procedure AssignError(Var T: Text);
  349. begin
  350. Assign(T,'');
  351. TextRec(T).OpenFunc:=@ErrorOpen;
  352. Rewrite(T);
  353. end;
  354. procedure SysInitStdIO;
  355. begin
  356. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  357. displayed in a messagebox }
  358. StdInputHandle:=longint(GetStdHandle(cardinal(STD_INPUT_HANDLE)));
  359. StdOutputHandle:=longint(GetStdHandle(cardinal(STD_OUTPUT_HANDLE)));
  360. StdErrorHandle:=longint(GetStdHandle(cardinal(STD_ERROR_HANDLE)));
  361. if not IsConsole then
  362. begin
  363. AssignError(stderr);
  364. AssignError(StdOut);
  365. Assign(Output,'');
  366. Assign(Input,'');
  367. Assign(ErrOutput,'');
  368. end
  369. else
  370. begin
  371. OpenStdIO(Input,fmInput,StdInputHandle);
  372. OpenStdIO(Output,fmOutput,StdOutputHandle);
  373. OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
  374. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  375. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  376. end;
  377. end;
  378. { ProcessID cached to avoid repeated calls to GetCurrentProcess. }
  379. var
  380. ProcessID: SizeUInt;
  381. function GetProcessID: SizeUInt;
  382. begin
  383. GetProcessID := ProcessID;
  384. end;
  385. {******************************************************************************
  386. Unicode
  387. ******************************************************************************}
  388. const
  389. { MultiByteToWideChar }
  390. MB_PRECOMPOSED = 1;
  391. WC_NO_BEST_FIT_CHARS = $400;
  392. function MultiByteToWideChar(CodePage:UINT; dwFlags:DWORD; lpMultiByteStr:PChar; cchMultiByte:longint; lpWideCharStr:PWideChar;cchWideChar:longint):longint;
  393. stdcall; external 'kernel32' name 'MultiByteToWideChar';
  394. function WideCharToMultiByte(CodePage:UINT; dwFlags:DWORD; lpWideCharStr:PWideChar; cchWideChar:longint; lpMultiByteStr:PChar;cchMultiByte:longint; lpDefaultChar:PChar; lpUsedDefaultChar:pointer):longint;
  395. stdcall; external 'kernel32' name 'WideCharToMultiByte';
  396. function CharUpperBuff(lpsz:LPWSTR; cchLength:DWORD):DWORD;
  397. stdcall; external 'user32' name 'CharUpperBuffW';
  398. function CharLowerBuff(lpsz:LPWSTR; cchLength:DWORD):DWORD;
  399. stdcall; external 'user32' name 'CharLowerBuffW';
  400. procedure Win32Unicode2AnsiMove(source:punicodechar;var dest:RawByteString;cp : TSystemCodePage;len:SizeInt);
  401. var
  402. destlen: SizeInt;
  403. begin
  404. // retrieve length including trailing #0
  405. // not anymore, because this must also be usable for single characters
  406. destlen:=WideCharToMultiByte(cp, 0, source, len, nil, 0, nil, nil);
  407. // this will null-terminate
  408. setlength(dest, destlen);
  409. if destlen>0 then
  410. begin
  411. WideCharToMultiByte(cp, 0, source, len, @dest[1], destlen, nil, nil);
  412. PAnsiRec(pointer(dest)-AnsiFirstOff)^.CodePage:=cp;
  413. end;
  414. end;
  415. procedure Win32Ansi2UnicodeMove(source:pchar;cp : TSystemCodePage;var dest:UnicodeString;len:SizeInt);
  416. var
  417. destlen: SizeInt;
  418. dwflags: DWORD;
  419. begin
  420. // retrieve length including trailing #0
  421. // not anymore, because this must also be usable for single characters
  422. if cp=CP_UTF8 then
  423. dwFlags:=0
  424. else
  425. dwFlags:=MB_PRECOMPOSED;
  426. destlen:=MultiByteToWideChar(cp, dwFlags, source, len, nil, 0);
  427. // this will null-terminate
  428. setlength(dest, destlen);
  429. if destlen>0 then
  430. begin
  431. MultiByteToWideChar(cp, dwFlags, source, len, @dest[1], destlen);
  432. PUnicodeRec(pointer(dest)-UnicodeFirstOff)^.CodePage:=CP_UTF16;
  433. end;
  434. end;
  435. function Win32UnicodeUpper(const s : UnicodeString) : UnicodeString;
  436. begin
  437. result:=s;
  438. UniqueString(result);
  439. if length(result)>0 then
  440. CharUpperBuff(LPWSTR(result),length(result));
  441. end;
  442. function Win32UnicodeLower(const s : UnicodeString) : UnicodeString;
  443. begin
  444. result:=s;
  445. UniqueString(result);
  446. if length(result)>0 then
  447. CharLowerBuff(LPWSTR(result),length(result));
  448. end;
  449. {******************************************************************************
  450. Widestring
  451. ******************************************************************************}
  452. procedure Win32Ansi2WideMove(source:pchar;cp : TSystemCodePage;var dest:widestring;len:SizeInt);
  453. var
  454. destlen: SizeInt;
  455. dwFlags: DWORD;
  456. begin
  457. // retrieve length including trailing #0
  458. // not anymore, because this must also be usable for single characters
  459. if cp=CP_UTF8 then
  460. dwFlags:=0
  461. else
  462. dwFlags:=MB_PRECOMPOSED;
  463. destlen:=MultiByteToWideChar(cp, dwFlags, source, len, nil, 0);
  464. // this will null-terminate
  465. setlength(dest, destlen);
  466. if destlen>0 then
  467. MultiByteToWideChar(cp, dwFlags, source, len, @dest[1], destlen);
  468. end;
  469. function Win32WideUpper(const s : WideString) : WideString;
  470. begin
  471. result:=s;
  472. if length(result)>0 then
  473. CharUpperBuff(LPWSTR(result),length(result));
  474. end;
  475. function Win32WideLower(const s : WideString) : WideString;
  476. begin
  477. result:=s;
  478. if length(result)>0 then
  479. CharLowerBuff(LPWSTR(result),length(result));
  480. end;
  481. type
  482. PWStrInitEntry = ^TWStrInitEntry;
  483. TWStrInitEntry = record
  484. addr: PPointer;
  485. data: Pointer;
  486. end;
  487. PWStrInitTablesTable = ^TWStrInitTablesTable;
  488. TWStrInitTablesTable = packed record
  489. count : longint;
  490. tables : packed array [1..32767] of PWStrInitEntry;
  491. end;
  492. {$if not(defined(VER2_2) or defined(VER2_4))}
  493. var
  494. WStrInitTablesTable: TWStrInitTablesTable; external name 'FPC_WIDEINITTABLES';
  495. {$endif}
  496. function GetACP:UINT; stdcall; external 'kernel32' name 'GetACP';
  497. function GetConsoleCP:UINT; stdcall; external 'kernel32' name 'GetConsoleCP';
  498. function Win32GetStandardCodePage(const stdcp: TStandardCodePageEnum): TSystemCodePage;
  499. begin
  500. case stdcp of
  501. scpAnsi,
  502. scpFileSystemSingleByte: Result := GetACP;
  503. scpConsoleInput: Result := GetConsoleCP;
  504. scpConsoleOutput: Result := GetConsoleOutputCP;
  505. end;
  506. end;
  507. { there is a similiar procedure in sysutils which inits the fields which
  508. are only relevant for the sysutils units }
  509. procedure InitWin32Widestrings;
  510. var
  511. i: longint;
  512. ptable: PWStrInitEntry;
  513. begin
  514. {$if not(defined(VER2_2) or defined(VER2_4))}
  515. { assign initial values to global Widestring typed consts }
  516. for i:=1 to WStrInitTablesTable.count do
  517. begin
  518. ptable:=WStrInitTablesTable.tables[i];
  519. while Assigned(ptable^.addr) do
  520. begin
  521. fpc_widestr_assign(ptable^.addr^, ptable^.data);
  522. Inc(ptable);
  523. end;
  524. end;
  525. {$endif}
  526. { Note: since WideChar=UnicodeChar and PWideChar=PUnicodeChar,
  527. Wide2AnsiMoveProc is identical to Unicode2AnsiStrMoveProc. }
  528. { Widestring }
  529. widestringmanager.Wide2AnsiMoveProc:=@Win32Unicode2AnsiMove;
  530. widestringmanager.Ansi2WideMoveProc:=@Win32Ansi2WideMove;
  531. widestringmanager.UpperWideStringProc:=@Win32WideUpper;
  532. widestringmanager.LowerWideStringProc:=@Win32WideLower;
  533. { Unicode }
  534. widestringmanager.Unicode2AnsiMoveProc:=@Win32Unicode2AnsiMove;
  535. widestringmanager.Ansi2UnicodeMoveProc:=@Win32Ansi2UnicodeMove;
  536. widestringmanager.UpperUnicodeStringProc:=@Win32UnicodeUpper;
  537. widestringmanager.LowerUnicodeStringProc:=@Win32UnicodeLower;
  538. { Codepage }
  539. widestringmanager.GetStandardCodePageProc:=@Win32GetStandardCodePage;
  540. DefaultSystemCodePage:=GetACP;
  541. DefaultUnicodeCodePage:=CP_UTF16;
  542. DefaultFileSystemCodePage:=DefaultSystemCodePage;
  543. DefaultRTLFileSystemCodePage:=DefaultFileSystemCodePage;
  544. end;