ndkutils.pas 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. {
  2. FPC Utility Functions for Native NT applications
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2009 by Sven Barth
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit NDKUtils;
  12. {$mode objfpc}{$H+}
  13. interface
  14. uses
  15. NDK;
  16. // Helpers for converting Pascal string types to NT's UNICODE_STRING
  17. procedure ShortStrToNTStr(aStr: ShortString; var aNTStr: UNICODE_STRING);
  18. procedure AnsiStrToNTStr(const aStr: String; var aNTStr: UNICODE_STRING);
  19. procedure UnicodeStrToNtStr(const aStr: UnicodeString;
  20. var aNTStr: UNICODE_STRING);
  21. procedure PCharToNTStr(aStr: PChar; aLen: Cardinal; var aNTStr: UNICODE_STRING);
  22. procedure FreeNTStr(var aNTStr: UNICODE_STRING);
  23. // Wraps NtDisplayString for use with Write(Ln)
  24. procedure AssignDisplayString(var aFile: Text; aUtf8: Boolean);
  25. implementation
  26. uses
  27. SysUtils;
  28. procedure ShortStrToNTStr(aStr: ShortString; var aNTStr: UNICODE_STRING);
  29. var
  30. buf: Pointer;
  31. i: Integer;
  32. begin
  33. aNTStr.Length := Length(aStr) * 2;
  34. aNTStr.buffer := GetMem(aNTStr.Length);
  35. buf := aNTStr.buffer;
  36. for i := 1 to Length(aStr) do begin
  37. PWord(buf)^ := Word(aStr[i]);
  38. buf := Pointer(PtrUInt(buf) + SizeOf(Word));
  39. end;
  40. aNTStr.MaximumLength := aNTStr.Length;
  41. end;
  42. procedure AnsiStrToNTStr(const aStr: String; var aNTStr: UNICODE_STRING);
  43. var
  44. buf: PWideChar;
  45. i: Integer;
  46. begin
  47. aNTStr.Length := Length(aStr) * 2;
  48. aNTStr.Buffer := GetMem(aNTStr.Length);
  49. buf := aNTStr.buffer;
  50. for i := 1 to Length(aStr) do begin
  51. buf^ := WideChar(Word(aStr[i]));
  52. Inc(buf);
  53. end;
  54. aNTStr.MaximumLength := aNTStr.Length;
  55. end;
  56. procedure UnicodeStrToNtStr(const aStr: UnicodeString;
  57. var aNTStr: UNICODE_STRING);
  58. var
  59. buf: PWideChar;
  60. begin
  61. { TODO : check why this prints garbage }
  62. aNTStr.Length := Length(aStr) * 2;
  63. aNTStr.Buffer := GetMem(aNTStr.Length);
  64. if Length(aStr) > 0 then
  65. Move(aStr[1], aNTStr.Buffer^, aNTStr.Length);
  66. aNTStr.MaximumLength := aNTStr.Length;
  67. end;
  68. procedure PCharToNTStr(aStr: PChar; aLen: Cardinal; var aNTStr: UNICODE_STRING);
  69. var
  70. i: Integer;
  71. begin
  72. if (aLen = 0) and (aStr <> Nil) and (aStr^ <> #0) then
  73. aLen := StrLen(aStr);
  74. aNtStr.Length := aLen * SizeOf(WideChar);
  75. aNtStr.MaximumLength := aNtStr.Length;
  76. aNtStr.Buffer := GetMem(aNtStr.Length);
  77. for i := 0 to aLen do
  78. aNtStr.Buffer[i] := aStr[i];
  79. end;
  80. procedure FreeNTStr(var aNTStr: UNICODE_STRING);
  81. begin
  82. if aNTStr.Buffer <> Nil then
  83. FreeMem(aNTStr.Buffer);
  84. FillChar(aNTStr, SizeOf(UNICODE_STRING), 0);
  85. end;
  86. function DisplayStringWriteFunc(var aFile: TTextRec ): LongInt;
  87. var
  88. ntstr: TNtUnicodeString;
  89. len: SizeUInt;
  90. begin
  91. Result := 0;
  92. with aFile do
  93. if (BufPos>0) then begin
  94. if Boolean(UserData[1]) then begin
  95. { TODO : check why UTF8 prints garbage }
  96. {len := Utf8ToUnicode(Nil, 0, PChar(BufPtr), BufPos);
  97. ntstr.Length := len * 2;
  98. ntstr.MaximumLength := ntstr.Length;
  99. ntstr.Buffer := GetMem(ntstr.Length);
  100. Utf8ToUnicode(ntstr.Buffer, len, PChar(BufPtr), BufPos);}
  101. PCharToNtStr(PChar(BufPtr), BufPos, ntstr);
  102. end else
  103. PCharToNtStr(PChar(BufPtr), BufPos, ntstr);
  104. NtDisplayString(@ntstr);
  105. // FreeNTStr uses FreeMem, so we don't need an If here
  106. FreeNtStr(ntstr);
  107. BufPos := 0;
  108. end;
  109. end;
  110. function DisplayStringCloseFunc(var aFile: TTextRec): LongInt;
  111. begin
  112. Result := 0;
  113. end;
  114. function DisplayStringOpenFunc(var aFile: TTextRec ): LongInt;
  115. begin
  116. Result := 0;
  117. end;
  118. procedure AssignDisplayString(var aFile: Text; aUtf8: Boolean);
  119. begin
  120. FillChar(aFile, SizeOf(TextRec), 0);
  121. { only set things that are not zero }
  122. TextRec(aFile).Handle := UnusedHandle;
  123. TextRec(aFile).mode := fmOutput;
  124. TextRec(aFile).BufSize := TextRecBufSize;
  125. TextRec(aFile).Bufptr := @TextRec(aFile).Buffer;
  126. TextRec(aFile).OpenFunc := @DisplayStringOpenFunc;
  127. case DefaultTextLineBreakStyle of
  128. tlbsLF:
  129. TextRec(aFile).LineEnd := #10;
  130. tlbsCRLF:
  131. TextRec(aFile).LineEnd := #13#10;
  132. tlbsCR:
  133. TextRec(aFile).LineEnd := #13;
  134. end;
  135. TextRec(aFile).Closefunc := @DisplayStringCloseFunc;
  136. TextRec(aFile).InOutFunc := @DisplayStringWriteFunc;
  137. TextRec(aFile).FlushFunc := @DisplayStringWriteFunc;
  138. TextRec(aFile).UserData[1] := Ord(aUTF8);
  139. end;
  140. end.