unit DPcInfoMain; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TJobInfo2Header = packed record JobId: DWORD; pPrinterName: DWORD; pMachineName: DWORD; pUserName: DWORD; pDocument: DWORD; pNotifyName: DWORD; pDatatype: DWORD; pPrintProcessor: DWORD; pParameters: DWORD; pDriverName: DWORD; pDevMode: DWORD; pStatus: DWORD; Status: DWORD; Priority: DWORD; Position: DWORD; StartTime: DWORD; UntilTime: DWORD; TotalPages: DWORD; Size: DWORD; Submitted: TSystemTime; Time: DWORD; PagesPrinted: DWORD; end; type TSpoolHeader = packed record Signature: DWORD; Unused1: array[0..7] of Byte; JobName: array[0..31] of WideChar; // Unicode DocumentName: array[0..127] of WideChar; PrinterName: array[0..31] of WideChar; UserName: array[0..31] of WideChar; SubmitTime: FILETIME; DataSize: DWORD; // 추가 필드 생략... end; TDlgPcInfoMain = class(TForm) mmInfo: TMemo; btnGetInfo: TButton; procedure btnGetInfoClick(Sender: TObject); private { Private declarations } procedure ParseSHDFile(const FileName: string); procedure AnalyzeSHD(const FileName: string); public { Public declarations } end; var DlgPcInfoMain: TDlgPcInfoMain; implementation uses Tocsg.WMI, Tocsg.Convert, Tocsg.Disk, Tocsg.Safe, Tocsg.Strings, Tocsg.Printer, Winapi.WinSpool, System.RegularExpressions, Tocsg.PCRE, Tocsg.Network, Tocsg.Hash; {$R *.dfm} function ReadUnicodeString(const Buffer: TBytes; Offset: Integer): string; var i: Integer; Ch: WideChar; begin Result := ''; i := Offset; while (i + 1 < Length(Buffer)) do begin Ch := WideChar(Buffer[i] or (Buffer[i+1] shl 8)); if Ch = #0 then Break; Result := Result + Ch; Inc(i, 2); end; end; procedure TDlgPcInfoMain.ParseSHDFile(const FileName: string); var FileStream: TFileStream; Buffer: TBytes; Header: TJobInfo2Header; StructOffset: Integer; begin FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone); try SetLength(Buffer, FileStream.Size); FileStream.Read(Buffer[0], FileStream.Size); // 오프셋은 0x04 위치에 있음 (DWORD = 구조체 시작위치) StructOffset := PInteger(@Buffer[4])^; // 구조체 읽기 if StructOffset + SizeOf(Header) > Length(Buffer) then begin Writeln('구조체 오프셋이 잘못되었습니다.'); Exit; end; Move(Buffer[StructOffset], Header, SizeOf(Header)); mmInfo.Lines.Add('문서 이름(Document) : ' + ReadUnicodeString(Buffer, Header.pDocument)); mmInfo.Lines.Add('사용자(User) : ' + ReadUnicodeString(Buffer, Header.pUserName)); mmInfo.Lines.Add('프린터 이름(Printer): ' + ReadUnicodeString(Buffer, Header.pPrinterName)); mmInfo.Lines.Add('드라이버(Driver) : ' + ReadUnicodeString(Buffer, Header.pDriverName)); mmInfo.Lines.Add('페이지 수(Pages) : ' + IntToStr(Header.TotalPages)); mmInfo.Lines.Add('파일 크기(Bytes) : ' + IntToStr(Header.Size)); with Header.Submitted do mmInfo.Lines.Add(Format('요청 시간(Submitted): %d-%02d-%02d %02d:%02d:%02d', [wYear, wMonth, wDay, wHour, wMinute, wSecond])); finally FileStream.Free; end; end; procedure TDlgPcInfoMain.AnalyzeSHD(const FileName: string); var F: TFileStream; Header: TSpoolHeader; SubmitTime: TDateTime; begin F := TFileStream.Create(FileName, fmOpenRead); try if F.Size < SizeOf(Header) then raise Exception.Create('Invalid SHD file size'); F.Read(Header, SizeOf(Header)); // 시그니처 확인 if Header.Signature <> $0000069C then raise Exception.Create('Invalid SHD signature'); // FILETIME -> TDateTime 변환 // SubmitTime := FileTimeToDateTime(Header.SubmitTime); // 정보 출력 mmInfo.Lines.Add('Job Name: ' + Header.JobName); mmInfo.Lines.Add('Document: ' + Header.DocumentName); mmInfo.Lines.Add('Printer: ' + Header.PrinterName); mmInfo.Lines.Add('User: ' + Header.UserName); mmInfo.Lines.Add('Submit Time: ' + DateTimeToStr(SubmitTime)); // mmInfo.Lines.Add('Data Size: ' + Header.DataSize, ' bytes'); finally F.Free; end; end; procedure SetConsoleFontToSupportKorean; var hConsole: THandle; FontInfo: CONSOLE_FONT_INFOEX; begin hConsole := GetStdHandle(STD_OUTPUT_HANDLE); ZeroMemory(@FontInfo, SizeOf(FontInfo)); FontInfo.cbSize := SizeOf(FontInfo); FontInfo.nFont := 0; FontInfo.dwFontSize.X := 8; FontInfo.dwFontSize.Y := 16; FontInfo.FontFamily := FF_DONTCARE; FontInfo.FontWeight := FW_NORMAL; // 한글 지원 폰트로 설정 StrCopy(FontInfo.FaceName, 'Consolas'); // 또는 'Gulim', 'Malgun Gothic' 등 한글 폰트 SetCurrentConsoleFontEx(hConsole, False, FontInfo); end; procedure TDlgPcInfoMain.btnGetInfoClick(Sender: TObject); var DrvList: TStringList; i: Integer; llSize: ULONGLONG; sDrvs: String; R: TRegEx; begin // if RemoveEveryoneFromShare('share') then // ShowMessage('성공'); sDrvs := 'C:\Users\kku\Desktop\The fault in our stars (안녕, 헤이즐).txt'; ShowMessage(GetFileToSha1Str(sDrvs)); exit; AllocConsole; SetTextCodePage(Output, CP_UTF8); SetConsoleOutputCP(CP_UTF8); SetConsoleCP(CP_UTF8); // SetConsoleFontToSupportKorean; // AssignFile(Output, ''); // Rewrite(Output); WriteLn('=== 한글 출력 테스트 ==='); WriteLn('Hello World!'); // 영어 WriteLn('한글 테스트'); // 한글 WriteLn('123 숫자'); // 숫자 + 한글 WriteLn(UTF8Encode('456 숫자')); // 숫자 + 한글 WriteLn('🍕 이모지 + 한글'); // 이모지 + 한글 var hConsole := GetStdHandle(STD_OUTPUT_HANDLE); var BytesWritten: DWORD; var str: AnsiString := UTF8Encode('=== 한글 출력 테스트 ===' + #13#10); WriteConsoleA(hConsole, PAnsiChar(str), Length(str), BytesWritten, nil); sDrvs := '=== 한글 출력 테스트 ===' + #13#10; WriteConsoleW(hConsole, PChar(sDrvs), Length(sDrvs), BytesWritten, nil); exit; mmInfo.Clear; mmInfo.Lines.Add('CPU : ' + WMI_GetCpuInfo); mmInfo.Lines.Add('Baseboard : ' + WMI_GetBaseboardInfo); mmInfo.Lines.Add('BIOS Version : ' + WMI_GetBiosVersion); mmInfo.Lines.Add('Graphic : ' + WMI_GetVideoController); mmInfo.Lines.Add('Memory : ' + ByteSizeToStr(WMI_GetMemory)); mmInfo.Lines.Add('Monitor : ' + WMI_GetMonitor); mmInfo.Lines.Add('OS Install Date : ' + FormatDateTime('yyyy-mm-dd hh:nn:ss', WMI_GetOSInstallDateTime)); Guard(DrvList, TStringList.Create); DrvList.CommaText := GetDrivesFromMask(GetLogicalDrives); for i := 0 to DrvList.Count - 1 do begin llSize := GetDriveSize(DrvList[i]); SumString(sDrvs, Format('%s (%s)', [DrvList[i], ByteSizeToStr(llSize)]), ', '); end; mmInfo.Lines.Add('Drive : ' + sDrvs); mmInfo.Lines.Add(''); ParseSHDFile('C:\Users\kku\Desktop\TEST\Printer\00004.SHD'); end; end.