sysutils.pp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. Sysutils unit for win32
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit sysutils;
  14. interface
  15. {$MODE objfpc}
  16. { force ansistrings }
  17. {$H+}
  18. uses
  19. dos,windows;
  20. { Include platform independent interface part }
  21. {$i sysutilh.inc}
  22. { platform dependent functions }
  23. function SysErrorMessage(ErrorCode: Integer): String;
  24. implementation
  25. { Include platform independent implementation part }
  26. {$i sysutils.inc}
  27. {****************************************************************************
  28. File Functions
  29. ****************************************************************************}
  30. Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
  31. const
  32. AccessMode: array[0..2] of Integer = (
  33. GENERIC_READ,
  34. GENERIC_WRITE,
  35. GENERIC_READ or GENERIC_WRITE);
  36. ShareMode: array[0..4] of Integer = (
  37. 0,
  38. 0,
  39. FILE_SHARE_READ,
  40. FILE_SHARE_WRITE,
  41. FILE_SHARE_READ or FILE_SHARE_WRITE);
  42. Var
  43. FN : string;
  44. begin
  45. FN:=FileName+#0;
  46. result := CreateFile(@FN[1], AccessMode[Mode and 3],
  47. ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING,
  48. FILE_ATTRIBUTE_NORMAL, 0);
  49. end;
  50. Function FileCreate (Const FileName : String) : Longint;
  51. Var
  52. FN : string;
  53. begin
  54. FN:=FileName+#0;
  55. Result := CreateFile(@FN[1], GENERIC_READ or GENERIC_WRITE,
  56. 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  57. end;
  58. Function FileRead (Handle : Longint; Var Buffer; Count : longint) : Longint;
  59. Var
  60. res : Longint;
  61. begin
  62. if not ReadFile(Handle, Buffer, Count, res, nil) then
  63. res := -1;
  64. FileRead:=Res;
  65. end;
  66. Function FileWrite (Handle : Longint; const Buffer; Count : Longint) : Longint;
  67. Var
  68. Res : longint;
  69. begin
  70. if not WriteFile(Handle, Buffer, Count, Res, nil) then
  71. Res:= -1;
  72. FileWrite:=Res;
  73. end;
  74. Function FileSeek (Handle,FOffset,Origin : Longint) : Longint;
  75. begin
  76. Result := SetFilePointer(Handle, FOffset, nil, Origin);
  77. end;
  78. Procedure FileClose (Handle : Longint);
  79. begin
  80. if Handle<=4 then
  81. exit;
  82. CloseHandle(Handle);
  83. end;
  84. Function FileTruncate (Handle,Size: Longint) : boolean;
  85. begin
  86. Result:=SetFilePointer(handle,Size,nil,FILE_BEGIN)<>-1;
  87. If Result then
  88. Result:=SetEndOfFile(handle);
  89. end;
  90. Function DosToWinTime (DTime:longint;Var Wtime : TFileTime):longbool;
  91. var
  92. lft : TFileTime;
  93. begin
  94. DosToWinTime:=DosDateTimeToFileTime(longrec(dtime).hi,longrec(dtime).lo,@lft) and
  95. LocalFileTimeToFileTime(lft,@Wtime);
  96. end;
  97. Function WinToDosTime (Var Wtime : TFileTime;var DTime:longint):longbool;
  98. var
  99. lft : FileTime;
  100. begin
  101. WinToDosTime:=FileTimeToLocalFileTime(WTime,@lft) and
  102. FileTimeToDosDateTime(lft,@Longrec(Dtime).Hi,@LongRec(DTIME).lo);
  103. end;
  104. Function FileAge (Const FileName : String): Longint;
  105. var
  106. Handle: THandle;
  107. FindData: TWin32FindData;
  108. begin
  109. Handle := FindFirstFile(Pchar(FileName), @FindData);
  110. if Handle <> INVALID_HANDLE_VALUE then
  111. begin
  112. Windows.FindClose(Handle);
  113. if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
  114. If WinToDosTime(FindData.ftLastWriteTime,Result) then
  115. exit;
  116. end;
  117. Result := -1;
  118. end;
  119. Function FileExists (Const FileName : String) : Boolean;
  120. var
  121. Handle: THandle;
  122. FindData: TWin32FindData;
  123. begin
  124. Handle := FindFirstFile(Pchar(FileName), @FindData);
  125. Result:=Handle <> INVALID_HANDLE_VALUE;
  126. If Result then
  127. Windows.FindClose(Handle);
  128. end;
  129. Function FindMatch(var f: TSearchRec) : Longint;
  130. begin
  131. { Find file with correct attribute }
  132. While (F.FindData.dwFileAttributes and F.ExcludeAttr)<>0 do
  133. begin
  134. if not FindNextFile (F.FindHandle,@F.FindData) then
  135. begin
  136. Result:=GetLastError;
  137. exit;
  138. end;
  139. end;
  140. { Convert some attributes back }
  141. WinToDosTime(F.FindData.ftLastWriteTime,F.Time);
  142. f.size:=F.FindData.NFileSizeLow;
  143. f.attr:=F.FindData.dwFileAttributes;
  144. f.Name:=StrPas(@F.FindData.cFileName);
  145. Result:=0;
  146. end;
  147. Function FindFirst (Const Path : String; Attr : Longint; Var Rslt : TSearchRec) : Longint;
  148. begin
  149. Rslt.Name:=Path;
  150. Rslt.Attr:=attr;
  151. Rslt.ExcludeAttr:=(not Attr) and ($1e);
  152. { $1e = faHidden or faSysFile or faVolumeID or faDirectory }
  153. { FindFirstFile is a Win32 Call }
  154. Rslt.FindHandle:=FindFirstFile (PChar(Path),@Rslt.FindData);
  155. If Rslt.FindHandle=Invalid_Handle_value then
  156. begin
  157. Result:=GetLastError;
  158. exit;
  159. end;
  160. { Find file with correct attribute }
  161. Result:=FindMatch(Rslt);
  162. end;
  163. Function FindNext (Var Rslt : TSearchRec) : Longint;
  164. begin
  165. if FindNextFile(Rslt.FindHandle, @Rslt.FindData) then
  166. Result := FindMatch(Rslt)
  167. else
  168. Result := GetLastError;
  169. end;
  170. Procedure FindClose (Var F : TSearchrec);
  171. begin
  172. if F.FindHandle <> INVALID_HANDLE_VALUE then
  173. Windows.FindClose(F.FindHandle);
  174. end;
  175. Function FileGetDate (Handle : Longint) : Longint;
  176. Var
  177. FT : TFileTime;
  178. begin
  179. If GetFileTime(Handle,nil,nil,@ft) and
  180. WinToDosTime(FT,Result) then
  181. exit;
  182. Result:=-1;
  183. end;
  184. Function FileSetDate (Handle,Age : Longint) : Longint;
  185. Var
  186. FT: TFileTime;
  187. begin
  188. Result := 0;
  189. if DosToWinTime(Age,FT) and
  190. SetFileTime(Handle, ft, ft, FT) then
  191. Exit;
  192. Result := GetLastError;
  193. end;
  194. Function FileGetAttr (Const FileName : String) : Longint;
  195. begin
  196. Result:=GetFileAttributes(PChar(FileName));
  197. end;
  198. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  199. begin
  200. if not SetFileAttributes(PChar(FileName), Attr) then
  201. Result := GetLastError
  202. else
  203. Result:=0;
  204. end;
  205. Function DeleteFile (Const FileName : String) : Boolean;
  206. begin
  207. DeleteFile:=Windows.DeleteFile(Pchar(FileName));
  208. end;
  209. Function RenameFile (Const OldName, NewName : String) : Boolean;
  210. begin
  211. Result := MoveFile(PChar(OldName), PChar(NewName));
  212. end;
  213. Function FileSearch (Const Name, DirList : String) : String;
  214. Var
  215. I : longint;
  216. Temp : String;
  217. begin
  218. Result:='';
  219. temp:=Dirlist;
  220. repeat
  221. I:=pos(';',Temp);
  222. If I<>0 then
  223. begin
  224. Result:=Copy (Temp,1,i-1);
  225. system.Delete(Temp,1,I);
  226. end
  227. else
  228. begin
  229. Result:=Temp;
  230. Temp:='';
  231. end;
  232. If result[length(result)]<>'\' then
  233. Result:=Result+'\';
  234. Result:=Result+name;
  235. If not FileExists(Result) Then
  236. Result:='';
  237. until (length(temp)=0) or (length(result)<>0);
  238. end;
  239. {****************************************************************************
  240. Disk Functions
  241. ****************************************************************************}
  242. function GetDiskFreeSpace(drive:pchar;var sector_cluster,bytes_sector,
  243. freeclusters,totalclusters:longint):longbool;
  244. external 'kernel32' name 'GetDiskFreeSpaceA';
  245. type
  246. TGetDiskFreeSpaceEx = function(drive:pchar;var availableforcaller,total,free):longbool;stdcall;
  247. var
  248. GetDiskFreeSpaceEx : TGetDiskFreeSpaceEx;
  249. function diskfree(drive : byte) : int64;
  250. var
  251. disk : array[1..4] of char;
  252. secs,bytes,
  253. free,total : longint;
  254. qwtotal,qwfree,qwcaller : int64;
  255. begin
  256. if drive=0 then
  257. begin
  258. disk[1]:='\';
  259. disk[2]:=#0;
  260. end
  261. else
  262. begin
  263. disk[1]:=chr(drive+64);
  264. disk[2]:=':';
  265. disk[3]:='\';
  266. disk[4]:=#0;
  267. end;
  268. if assigned(GetDiskFreeSpaceEx) then
  269. begin
  270. if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
  271. diskfree:=qwfree
  272. else
  273. diskfree:=-1;
  274. end
  275. else
  276. begin
  277. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  278. diskfree:=int64(free)*secs*bytes
  279. else
  280. diskfree:=-1;
  281. end;
  282. end;
  283. function disksize(drive : byte) : int64;
  284. var
  285. disk : array[1..4] of char;
  286. secs,bytes,
  287. free,total : longint;
  288. qwtotal,qwfree,qwcaller : int64;
  289. begin
  290. if drive=0 then
  291. begin
  292. disk[1]:='\';
  293. disk[2]:=#0;
  294. end
  295. else
  296. begin
  297. disk[1]:=chr(drive+64);
  298. disk[2]:=':';
  299. disk[3]:='\';
  300. disk[4]:=#0;
  301. end;
  302. if assigned(GetDiskFreeSpaceEx) then
  303. begin
  304. if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
  305. disksize:=qwtotal
  306. else
  307. disksize:=-1;
  308. end
  309. else
  310. begin
  311. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  312. disksize:=int64(total)*secs*bytes
  313. else
  314. disksize:=-1;
  315. end;
  316. end;
  317. Function GetCurrentDir : String;
  318. begin
  319. GetDir(0, result);
  320. end;
  321. Function SetCurrentDir (Const NewDir : String) : Boolean;
  322. begin
  323. {$I-}
  324. ChDir(NewDir);
  325. {$I+}
  326. result := (IOResult = 0);
  327. end;
  328. Function CreateDir (Const NewDir : String) : Boolean;
  329. begin
  330. {$I-}
  331. MkDir(NewDir);
  332. {$I+}
  333. result := (IOResult = 0);
  334. end;
  335. Function RemoveDir (Const Dir : String) : Boolean;
  336. begin
  337. {$I-}
  338. RmDir(Dir);
  339. {$I+}
  340. result := (IOResult = 0);
  341. end;
  342. {****************************************************************************
  343. Time Functions
  344. ****************************************************************************}
  345. Procedure GetLocalTime(var SystemTime: TSystemTime);
  346. Var
  347. Syst : Windows.TSystemtime;
  348. begin
  349. windows.Getlocaltime(@syst);
  350. SystemTime.year:=syst.wYear;
  351. SystemTime.month:=syst.wMonth;
  352. SystemTime.day:=syst.wDay;
  353. SystemTime.hour:=syst.wHour;
  354. SystemTime.minute:=syst.wMinute;
  355. SystemTime.second:=syst.wSecond;
  356. SystemTime.millisecond:=syst.wMilliSeconds;
  357. end;
  358. {****************************************************************************
  359. Misc Functions
  360. ****************************************************************************}
  361. procedure Beep;
  362. begin
  363. MessageBeep(0);
  364. end;
  365. {****************************************************************************
  366. Locale Functions
  367. ****************************************************************************}
  368. Procedure InitAnsi;
  369. Var
  370. i : longint;
  371. begin
  372. { Fill table entries 0 to 127 }
  373. for i := 0 to 96 do
  374. UpperCaseTable[i] := chr(i);
  375. for i := 97 to 122 do
  376. UpperCaseTable[i] := chr(i - 32);
  377. for i := 123 to 191 do
  378. UpperCaseTable[i] := chr(i);
  379. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  380. for i := 0 to 64 do
  381. LowerCaseTable[i] := chr(i);
  382. for i := 65 to 90 do
  383. LowerCaseTable[i] := chr(i + 32);
  384. for i := 91 to 191 do
  385. LowerCaseTable[i] := chr(i);
  386. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  387. end;
  388. function GetLocaleStr(LID, LT: Longint; const Def: string): ShortString;
  389. var
  390. L: Integer;
  391. Buf: array[0..255] of Char;
  392. begin
  393. L := GetLocaleInfo(LID, LT, Buf, SizeOf(Buf));
  394. if L > 0 then
  395. SetString(Result, @Buf[0], L - 1)
  396. else
  397. Result := Def;
  398. end;
  399. function GetLocaleChar(LID, LT: Longint; Def: Char): Char;
  400. var
  401. Buf: array[0..1] of Char;
  402. begin
  403. if GetLocaleInfo(LID, LT, Buf, 2) > 0 then
  404. Result := Buf[0]
  405. else
  406. Result := Def;
  407. end;
  408. Function GetLocaleInt(LID,TP,Def: LongInt): LongInt;
  409. Var
  410. S: String;
  411. C: Integer;
  412. Begin
  413. S:=GetLocaleStr(LID,TP,'0');
  414. Val(S,Result,C);
  415. If C<>0 Then
  416. Result:=Def;
  417. End;
  418. procedure GetFormatSettings;
  419. var
  420. HF : Shortstring;
  421. LID : LCID;
  422. I,Day,DateOrder : longint;
  423. begin
  424. LID := GetThreadLocale;
  425. { Date stuff }
  426. for I := 1 to 12 do
  427. begin
  428. ShortMonthNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVMONTHNAME1+I-1,ShortMonthNames[i]);
  429. LongMonthNames[I]:=GetLocaleStr(LID,LOCALE_SMONTHNAME1+I-1,LongMonthNames[i]);
  430. end;
  431. for I := 1 to 7 do
  432. begin
  433. Day := (I + 5) mod 7;
  434. ShortDayNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVDAYNAME1+Day,ShortDayNames[i]);
  435. LongDayNames[I]:=GetLocaleStr(LID,LOCALE_SDAYNAME1+Day,LongDayNames[i]);
  436. end;
  437. DateSeparator := GetLocaleChar(LID, LOCALE_SDATE, '/');
  438. DateOrder := GetLocaleInt(LID, LOCALE_IDate, 0);
  439. Case DateOrder Of
  440. 1: Begin
  441. ShortDateFormat := 'dd/mm/yyyy';
  442. LongDateFormat := 'dddd, d. mmmm yyyy';
  443. End;
  444. 2: Begin
  445. ShortDateFormat := 'yyyy/mm/dd';
  446. LongDateFormat := 'dddd, yyyy mmmm d.';
  447. End;
  448. else
  449. // Default american settings...
  450. ShortDateFormat := 'mm/dd/yyyy';
  451. LongDateFormat := 'dddd, mmmm d. yyyy';
  452. End;
  453. { Time stuff }
  454. TimeSeparator := GetLocaleChar(LID, LOCALE_STIME, ':');
  455. TimeAMString := GetLocaleStr(LID, LOCALE_S1159, 'AM');
  456. TimePMString := GetLocaleStr(LID, LOCALE_S2359, 'PM');
  457. if StrToIntDef(GetLocaleStr(LID, LOCALE_ITLZERO, '0'), 0) = 0 then
  458. HF:='h'
  459. else
  460. HF:='hh';
  461. // No support for 12 hour stuff at the moment...
  462. ShortTimeFormat := HF+':mm';
  463. LongTimeFormat := HF + ':mm:ss';
  464. { Currency stuff }
  465. CurrencyString:=GetLocaleStr(LID, LOCALE_SCURRENCY, '');
  466. CurrencyFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRENCY, '0'), 0);
  467. NegCurrFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_INEGCURR, '0'), 0);
  468. { Number stuff }
  469. ThousandSeparator:=GetLocaleChar(LID, LOCALE_STHOUSAND, ',');
  470. DecimalSeparator:=GetLocaleChar(LID, LOCALE_SDECIMAL, '.');
  471. CurrencyDecimals:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRDIGITS, '0'), 0);
  472. end;
  473. Procedure InitInternational;
  474. begin
  475. InitAnsi;
  476. GetFormatSettings;
  477. end;
  478. {****************************************************************************
  479. Target Dependent
  480. ****************************************************************************}
  481. function FormatMessageA(dwFlags : DWORD;
  482. lpSource : Pointer;
  483. dwMessageId : DWORD;
  484. dwLanguageId: DWORD;
  485. lpBuffer : PCHAR;
  486. nSize : DWORD;
  487. Arguments : Pointer): DWORD; external 'kernel32' name 'FormatMessageA';
  488. function SysErrorMessage(ErrorCode: Integer): String;
  489. const
  490. MaxMsgSize = Format_Message_Max_Width_Mask;
  491. var
  492. MsgBuffer: pChar;
  493. begin
  494. GetMem(MsgBuffer, MaxMsgSize);
  495. FillChar(MsgBuffer^, MaxMsgSize, #0);
  496. FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
  497. nil,
  498. ErrorCode,
  499. MakeLangId(LANG_NEUTRAL, SUBLANG_DEFAULT),
  500. MsgBuffer, { This function allocs the memory }
  501. MaxMsgSize, { Maximum message size }
  502. nil);
  503. SysErrorMessage := StrPas(MsgBuffer);
  504. FreeMem(MsgBuffer, MaxMsgSize);
  505. end;
  506. {****************************************************************************
  507. Initialization code
  508. ****************************************************************************}
  509. Initialization
  510. InitExceptions; { Initialize exceptions. OS independent }
  511. InitInternational; { Initialize internationalization settings }
  512. Finalization
  513. OutOfMemory.Free;
  514. InValidPointer.Free;
  515. end.
  516. {
  517. $Log$
  518. Revision 1.2 2000-08-20 15:46:46 peter
  519. * sysutils.pp moved to target and merged with disk.inc, filutil.inc
  520. }