{"id":403,"date":"2009-05-17T22:12:00","date_gmt":"2009-05-17T02:12:00","guid":{"rendered":""},"modified":"2013-11-17T19:19:17","modified_gmt":"2013-11-17T11:19:17","slug":"%e8%8e%b7%e5%8f%96%e7%b3%bb%e7%bb%9f%e4%bf%a1%e6%81%af%e5%8d%95%e5%85%83getsysinfo-pas","status":"publish","type":"post","link":"https:\/\/kyle.ai\/blog\/403.html","title":{"rendered":"\u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u5355\u5143GetSysInfo.pas"},"content":{"rendered":"<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n{****************Delphi\u5e38\u7528\u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u7684\u51fd\u6570*********************}\r\nunit GetSysInfo;\r\n\r\ninterface\r\n\r\nuses\r\nWindows, SysUtils, ShellAPI, WinSock, Registry;\r\n\r\nconst\r\nVER_NT_WORKSTATION = $00000001;\r\nVER_NT_DOMAIN_CONTROLLER = $00000002;\r\nVER_NT_SERVER = $00000003;\r\n\r\nVER_SERVER_NT = $80000000;\r\nVER_WORKSTATION_NT = $40000000;\r\n\r\nVER_SUITE_SMALLBUSINESS = $00000001;\r\nVER_SUITE_ENTERPRISE = $00000002;\r\nVER_SUITE_BACKOFFICE = $00000004;\r\nVER_SUITE_COMMUNICATIONS = $00000008;\r\nVER_SUITE_TERMINAL = $00000010;\r\nVER_SUITE_SMALLBUSINESS_RESTRICTED = $00000020;\r\nVER_SUITE_DATACENTER = $00000080;\r\nVER_SUITE_SINGLEUSERTS = $00000100;\r\nVER_SUITE_PERSONAL = $00000200;\r\nVER_SUITE_BLADE = $00000400;\r\n\r\ntype\r\nPOSVersionInfoEx = ^TOSVersionInfoEx;\r\nOSVERSIONINFOEXA = record\r\n    dwOSVersionInfoSize: DWORD;\r\n    dwMajorVersion: DWORD;\r\n    dwMinorVersion: DWORD;\r\n    dwBuildNumber: DWORD;\r\n    dwPlatformId: DWORD;\r\n    szCSDVersion: array&#x5B;0..127] of AnsiChar;\r\n    wServicePackMajor: WORD;\r\n    wServicePackMinor: WORD;\r\n    wSuiteMask: WORD;\r\n    wProductType: BYTE;\r\n    wReserved: BYTE;\r\nend;\r\nOSVERSIONINFOEXW = record\r\n    dwOSVersionInfoSize: DWORD;\r\n    dwMajorVersion: DWORD;\r\n    dwMinorVersion: DWORD;\r\n    dwBuildNumber: DWORD;\r\n    dwPlatformId: DWORD;\r\n    szCSDVersion: array&#x5B;0..127] of WideChar;\r\n    wServicePackMajor: WORD;\r\n    wServicePackMinor: WORD;\r\n    wSuiteMask: WORD;\r\n    wProductType: BYTE;\r\n    wReserved: BYTE;\r\nend;\r\nOSVERSIONINFOEX = OSVERSIONINFOEXA;\r\nTOSVersionInfoEx = OSVERSIONINFOEX;\r\n\r\nfunction SubString(sValue: string): string; \/\/\u62f7\u8d1d\u5b57\u7b26\u4e32\r\nfunction ReplaceString(sValue: string): string; \/\/\u5220\u9664\u5b57\u7b26\u4e32\r\nfunction GetIdeDiskSerialNumber: string; \/\/\u83b7\u5f97\u672c\u673a\u7684\u786c\u76d8ID\u53f7\r\nfunction LocalIP: string; \/\/\u83b7\u5f97\u672c\u673a\u7684ip\u5730\u5740\r\nfunction GetLocalHost: string; \/\/\u83b7\u53d6\u8ba1\u7b97\u673a\u540d\u79f0\r\nfunction GetCurrentUserName: string; \/\/\u83b7\u53d6\u5f53\u524d\u8ba1\u7b97\u673a\u7528\u6237\r\nfunction GetWindowsVersion: string; \/\/\u83b7\u53d6\u7cfb\u7edf\u7248\u672c\u53f7\r\nfunction GetMemory: string; \/\/GlobalMemoryStatus\u51fd\u6570\u83b7\u53d6\u5185\u5b58\u4f7f\u7528\u4fe1\u606f\r\nfunction GetDiskID(disk:PWidechar):string;\/\/\u83b7\u53d6\u786c\u76d8\u5e8f\u5217\u53f7 \uff0cdisk\u4e3a\u76d8\u7b26\r\n\r\nimplementation\r\n\r\nfunction GetDiskID(disk:PWidechar):string;\r\n\/\/\u8c03\u7528    Showmessage(GetDiskID('d:\\'));\r\nvar\r\n  VolumeSerialNumber : DWORD;\r\n  MaximumComponentLength : DWORD;\r\n  FileSystemFlags : DWORD;\r\nbegin\r\n  GetVolumeInformation(disk,nil,0,@VolumeSerialNumber,MaximumComponentLength,FileSystemFlags,nil,0);\r\n  result := inttostr(Volumeserialnumber);\r\nend;\r\n\r\n\/\/\u83b7\u53d6\u8ba1\u7b97\u673a\u540d\u79f0\r\nfunction GetLocalHost: string;\r\nvar\r\narr: array&#x5B;0..MAX_COMPUTERNAME_LENGTH] of char;\r\nd: DWORD;\r\nbegin\r\nd := SizeOf(arr);\r\nGetComputerName(arr, d);\r\nresult := string(arr);\r\nend;\r\n\r\nfunction SubString(sValue: string): string;\r\nbegin\r\nResult := Copy(sValue, 1, Pos('|', sValue) - 1);\r\nend;\r\n\r\nfunction ReplaceString(sValue: string): string;\r\nbegin\r\nResult := StringReplace(sValue, Copy(sValue, 1, Pos('|', sValue)), '', &#x5B;rfIgnoreCase]);\r\nend;\r\n\r\n\/\/GlobalMemoryStatus\u51fd\u6570\u83b7\u53d6\u5185\u5b58\u4f7f\u7528\u4fe1\u606f\r\nfunction GetMemory: string;\r\nvar\r\nMemStatus: TMemoryStatus; \/\/\u5b9a\u4e49\u5185\u5b58\u7ed3\u6784\u53d8\u91cf\r\nbegin\r\n\/\/ MemStatus.dwLength := Size of(MEMORYSTATUS);\r\nGlobalMemoryStatus(MemStatus); \/\/\u8fd4\u56de\u5185\u5b58\u4f7f\u7528\u4fe1\u606f\r\nResult := Format('\u53ef\u7528\u5185\u5b58: %dMB', &#x5B;MemStatus.dwTotalPhys div 1048576]);\r\nend;\r\n\r\n\/\/\u83b7\u53d6\u786c\u76d8\u5e8f\u5217\u53f7\r\nfunction GetIdeDiskSerialNumber: string;\r\ntype\r\nTSrbIoControl = packed record\r\n    HeaderLength: ULONG;\r\n    Signature: array&#x5B;0..7] of Char;\r\n    Timeout: ULONG;\r\n    ControlCode: ULONG;\r\n    ReturnCode: ULONG;\r\n    Length: ULONG;\r\nend;\r\nSRB_IO_CONTROL = TSrbIoControl;\r\nPSrbIoControl = ^TSrbIoControl;\r\n\r\nTIDERegs = packed record\r\n    bFeaturesReg: Byte; \/\/ Used for specifying SMART &quot;commands&quot;.\r\n    bSectorCountReg: Byte; \/\/ IDE sector count register\r\n    bSectorNumberReg: Byte; \/\/ IDE sector number register\r\n    bCylLowReg: Byte; \/\/ IDE low order cylinder value\r\n    bCylHighReg: Byte; \/\/ IDE high order cylinder value\r\n    bDriveHeadReg: Byte; \/\/ IDE drive\/head register\r\n    bCommandReg: Byte; \/\/ Actual IDE command.\r\n    bReserved: Byte; \/\/ reserved for future use. Must be zero.\r\nend;\r\nIDEREGS = TIDERegs;\r\nPIDERegs = ^TIDERegs;\r\n\r\nTSendCmdInParams = packed record\r\n    cBufferSize: DWORD; \/\/ Buffer size in bytes\r\n    irDriveRegs: TIDERegs; \/\/ Structure with drive register values.\r\n    bDriveNumber: Byte; \/\/ Physical drive number to send command to (0,1,2,3).\r\n    bReserved: array&#x5B;0..2] of Byte; \/\/ Reserved for future expansion.\r\n    dwReserved: array&#x5B;0..3] of DWORD; \/\/ For future use.\r\n    bBuffer: array&#x5B;0..0] of Byte; \/\/ Input buffer.\r\nend;\r\nSENDCMDINPARAMS = TSendCmdInParams;\r\nPSendCmdInParams = ^TSendCmdInParams;\r\n\r\nTIdSector = packed record\r\n    wGenConfig: Word;\r\n    wNumCyls: Word;\r\n    wReserved: Word;\r\n    wNumHeads: Word;\r\n    wBytesPerTrack: Word;\r\n    wBytesPerSector: Word;\r\n    wSectorsPerTrack: Word;\r\n    wVendorUnique: array&#x5B;0..2] of Word;\r\n    sSerialNumber: array&#x5B;0..19] of Char;\r\n    wBufferType: Word;\r\n    wBufferSize: Word;\r\n    wECCSize: Word;\r\n    sFirmwareRev: array&#x5B;0..7] of Char;\r\n    sModelNumber: array&#x5B;0..39] of Char;\r\n    wMoreVendorUnique: Word;\r\n    wDoubleWordIO: Word;\r\n    wCapabilities: Word;\r\n    wReserved1: Word;\r\n    wPIOTiming: Word;\r\n    wDMATiming: Word;\r\n    wBS: Word;\r\n    wNumCurrentCyls: Word;\r\n    wNumCurrentHeads: Word;\r\n    wNumCurrentSectorsPerTrack: Word;\r\n    ulCurrentSectorCapacity: ULONG;\r\n    wMultSectorStuff: Word;\r\n    ulTotalAddressableSectors: ULONG;\r\n    wSingleWordDMA: Word;\r\n    wMultiWordDMA: Word;\r\n    bReserved: array&#x5B;0..127] of Byte;\r\nend;\r\nPIdSector = ^TIdSector;\r\n\r\nconst\r\nIDE_ID_FUNCTION = $EC;\r\nIDENTIFY_BUFFER_SIZE = 512;\r\nDFP_RECEIVE_DRIVE_DATA = $0007C088;\r\nIOCTL_SCSI_MINIPORT = $0004D008;\r\nIOCTL_SCSI_MINIPORT_IDENTIFY = $001B0501;\r\nDataSize = sizeof(TSendCmdInParams) - 1 + IDENTIFY_BUFFER_SIZE;\r\nBufferSize = SizeOf(SRB_IO_CONTROL) + DataSize;\r\nW9xBufferSize = IDENTIFY_BUFFER_SIZE + 16;\r\nvar\r\nhDevice: THandle;\r\ncbBytesReturned: DWORD;\r\npInData: PSendCmdInParams;\r\npOutData: Pointer; \/\/ PSendCmdInParams;\r\nBuffer: array&#x5B;0..BufferSize - 1] of Byte;\r\nsrbControl: TSrbIoControl absolute Buffer;\r\n\r\nprocedure ChangeByteOrder(var Data; Size: Integer);\r\nvar ptr: PChar;\r\n    i: Integer;\r\n    c: Char;\r\nbegin\r\n    ptr := @Data;\r\n    for i := 0 to (Size shr 1) - 1 do\r\n    begin\r\n      c := ptr^;\r\n      ptr^ := (ptr + 1)^;\r\n      (ptr + 1)^ := c;\r\n      Inc(ptr, 2);\r\n    end;\r\nend;\r\n\r\nbegin\r\nResult := '';\r\nFillChar(Buffer, BufferSize, #0);\r\nif Win32Platform = VER_PLATFORM_WIN32_NT then\r\nbegin \/\/ Windows NT, Windows 2000\r\n      \/\/ Get SCSI port handle\r\n    hDevice := CreateFile('\\\\.\\Scsi0:', GENERIC_READ or GENERIC_WRITE,\r\n      FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);\r\n    if hDevice = INVALID_HANDLE_VALUE then Exit;\r\n    try\r\n      srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);\r\n      System.Move('SCSIDISK', srbControl.Signature, 8);\r\n      srbControl.Timeout := 2;\r\n      srbControl.Length := DataSize;\r\n      srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;\r\n      pInData := PSendCmdInParams(PChar(@Buffer) + SizeOf(SRB_IO_CONTROL));\r\n      pOutData := pInData;\r\n      with pInData^ do\r\n      begin\r\n        cBufferSize := IDENTIFY_BUFFER_SIZE;\r\n        bDriveNumber := 0;\r\n        with irDriveRegs do\r\n        begin\r\n          bFeaturesReg := 0;\r\n          bSectorCountReg := 1;\r\n          bSectorNumberReg := 1;\r\n          bCylLowReg := 0;\r\n          bCylHighReg := 0;\r\n          bDriveHeadReg := $A0;\r\n          bCommandReg := IDE_ID_FUNCTION;\r\n        end;\r\n      end;\r\n      if not DeviceIoControl(hDevice, IOCTL_SCSI_MINIPORT, @Buffer, BufferSize, @Buffer, BufferSize, cbBytesReturned, nil) then Exit;\r\n    finally\r\n      CloseHandle(hDevice);\r\n    end;\r\nend\r\nelse\r\nbegin \/\/ Windows 95 OSR2, Windows 98\r\n    hDevice := CreateFile('\\\\.\\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);\r\n    if hDevice = INVALID_HANDLE_VALUE then Exit;\r\n    try\r\n      pInData := PSendCmdInParams(@Buffer);\r\n      pOutData := PChar(@pInData^.bBuffer);\r\n      with pInData^ do\r\n      begin\r\n        cBufferSize := IDENTIFY_BUFFER_SIZE;\r\n        bDriveNumber := 0;\r\n        with irDriveRegs do\r\n        begin\r\n          bFeaturesReg := 0;\r\n          bSectorCountReg := 1;\r\n          bSectorNumberReg := 1;\r\n          bCylLowReg := 0;\r\n          bCylHighReg := 0;\r\n          bDriveHeadReg := $A0;\r\n          bCommandReg := IDE_ID_FUNCTION;\r\n        end;\r\n      end;\r\n      if not DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA, pInData, SizeOf(TSendCmdInParams) - 1, pOutData, W9xBufferSize, cbBytesReturned, nil) then Exit;\r\n    finally\r\n      CloseHandle(hDevice);\r\n    end;\r\nend;\r\nwith PIdSector(PChar(pOutData) + 16)^ do\r\nbegin\r\n    ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));\r\n    SetString(Result, sSerialNumber, SizeOf(sSerialNumber));\r\nend;\r\nend;\r\n\r\n\/\/\u83b7\u5f97\u672c\u673a\u7684ip\u5730\u5740\r\nfunction LocalIP: string;\r\ntype\r\nTaPInAddr = array&#x5B;0..10] of PInAddr;\r\nPaPInAddr = ^TaPInAddr;\r\nvar\r\nphe: PHostEnt;\r\npptr: PaPInAddr;\r\nBuffer: PAnsichar;\r\nI: Integer;\r\nGInitData: TWSADATA;\r\nbegin\r\nbuffer:='';\r\nWSAStartup($101, GInitData);\r\nResult := '';\r\nGetHostName(Buffer, SizeOf(Buffer));\r\nphe := GetHostByName(buffer);\r\nif phe = nil then Exit;\r\npptr := PaPInAddr(Phe^.h_addr_list);\r\nI := 0;\r\nwhile pptr^&#x5B;I] &lt;&gt; nil do begin\r\n    result :=string( StrPas(inet_ntoa(pptr^&#x5B;I]^)));\r\n    Inc(I);\r\nend;\r\nWSACleanup;\r\nend;\r\n\r\n\/\/\u5f53\u524d\u7528\u6237\u540d\r\nfunction GetCurrentUserName: string;\r\nconst\r\ncnMaxUserNameLen = 254;\r\nvar\r\nsUserName: string; dwUserNameLen: DWord;\r\nbegin\r\ndwUserNameLen := cnMaxUserNameLen - 1;\r\nSetLength(sUserName, cnMaxUserNameLen);\r\nGetUserName(PChar(sUserName), dwUserNameLen); SetLength(sUserName, dwUserNameLen);\r\nResult := sUserName;\r\nend;\r\n\r\n\/\/\u83b7\u53d6\u7cfb\u7edf\u7248\u672c\u53f7\r\nfunction GetWindowsVersion: string; \/\/\u53d6\u7cfb\u7edf\u7248\u672c\u53f7\uff08\u5b57\u7b26\u4e32\u5f62\u5f0f\uff09\r\nvar\r\nosVerInfo: TOSVersionInfoEx;\r\nExVerExist: Boolean;\r\nProductType: string;\r\nbegin\r\nResult := 'Microsoft Windows';\r\nExVerExist := True;\r\nosVerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfoEx);\r\nif not GetVersionEx(POSVersionInfo(@osVerInfo)^) then\r\nbegin\r\n    osVerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);\r\n    GetVersionEx(POSVersionInfo(@osVerInfo)^);\r\n    ExVerExist := False;\r\nend;\r\nwith osVerInfo do\r\nbegin\r\n    case dwPlatformId of\r\n      VER_PLATFORM_WIN32s: Result := Result + Format(' %d.%d', &#x5B;dwMajorVersion, dwMinorVersion]);\r\n      VER_PLATFORM_WIN32_WINDOWS: { Windows 9x\/ME }\r\n        begin\r\n          if (dwMajorVersion = 4) and (dwMinorVersion = 0) then\r\n          begin\r\n            Result := Result + ' 95';\r\n            if szCSDVersion&#x5B;1] in &#x5B;'B', 'C'] then\r\n              Result := Result + ' OSR2';\r\n          end\r\n          else if (dwMajorVersion = 4) and (dwMinorVersion = 10) then\r\n          begin\r\n            Result := Result + ' 98';\r\n            if (osVerInfo.szCSDVersion&#x5B;1] = 'A') then\r\n              Result := Result + ' Second Edition';\r\n          end\r\n          else if (dwMajorVersion = 4) and (dwMinorVersion = 90) then\r\n            Result := Result + ' Millenium Edition';\r\n        end;\r\n      VER_PLATFORM_WIN32_NT: { Windows NT\/2000 }\r\n        begin\r\n          case dwMajorVersion of\r\n            3, 4: Result := Result + Format(' NT %d.%d', &#x5B;dwMajorVersion, dwMinorVersion]);\r\n            5: begin\r\n                if dwMinorVersion = 0 then\r\n                  Result := Result + ' 2000'\r\n                else if dwMinorVersion = 1 then\r\n                  Result := Result + ' XP'\r\n                else if dwMinorVersion = 2 then\r\n                  Result := Result + ' 2003 Server';\r\n              end;\r\n          end;\r\n\r\n          if ExVerExist then\r\n          begin\r\n            if wProductType = VER_NT_WORKSTATION then\r\n            begin\r\n              if dwMajorVersion = 4 then\r\n                Result := Result + ' Workstation'\r\n              else if wSuiteMask and VER_SUITE_PERSONAL &lt;&gt; 0 then\r\n                Result := Result + ' Home Edition'\r\n              else\r\n                Result := Result + ' Professional';\r\n            end\r\n            else if wProductType = VER_NT_SERVER then\r\n            begin\r\n              if (dwMajorVersion = 5) and (dwMinorVersion = 2) then\r\n              begin\r\n                if wSuiteMask and VER_SUITE_DATACENTER &lt;&gt; 0 then\r\n                  Result := Result + ' Datacenter Edition'\r\n                else if wSuiteMask and VER_SUITE_ENTERPRISE &lt;&gt; 0 then\r\n                  Result := Result + ' Enterprise Edition'\r\n                else if wSuiteMask and VER_SUITE_BLADE &lt;&gt; 0 then\r\n                  Result := Result + ' Web Edition'\r\n                else\r\n                  Result := Result + ' Standard Edition';\r\n              end\r\n              else if (dwMajorVersion = 5) and (dwMinorVersion = 0) then\r\n              begin\r\n                if wSuiteMask and VER_SUITE_DATACENTER &lt;&gt; 0 then\r\n                  Result := Result + ' Datacenter Server'\r\n                else if wSuiteMask and VER_SUITE_ENTERPRISE &lt;&gt; 0 then\r\n                  Result := Result + ' Advanced Server'\r\n                else\r\n                  Result := Result + ' Server'\r\n              end\r\n              else\r\n              begin\r\n                Result := Result + ' Server';\r\n                if wSuiteMask and VER_SUITE_ENTERPRISE &lt;&gt; 0 then\r\n                  Result := Result + ' Enterprise Edition';\r\n              end;\r\n            end;\r\n          end\r\n          else\r\n          begin\r\n            with TRegistry.Create do\r\n            begin\r\n              try\r\n                RootKey := HKEY_LOCAL_MACHINE;\r\n                if OpenKey('\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions', False) then\r\n                begin\r\n                  if ValueExists('ProductType') then\r\n                  begin\r\n                    ProductType := ReadString('ProductType');\r\n                    if SameText(ProductType, 'WinNT') then\r\n                      Result := Result + ' Workstation'\r\n                    else if SameText(ProductType, 'LanManNT') then\r\n                      Result := Result + ' Server'\r\n                    else if SameText(ProductType, 'ServerNT') then\r\n                      Result := Result + ' Advance Server';\r\n                  end;\r\n                  CloseKey;\r\n                end;\r\n              finally\r\n                Free;\r\n              end;\r\n            end;\r\n          end;\r\n\r\n          Result :=Result + ' ' +string( szCSDVersion);\r\n          if (dwMajorVersion = 4) and SameText(string(szCSDVersion), 'Service Pack 6') then\r\n          begin\r\n            with TRegistry.Create do\r\n            begin\r\n              try\r\n                RootKey := HKEY_LOCAL_MACHINE;\r\n                if OpenKey('\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009', False) then\r\n                begin\r\n                  Result := Result + 'a';\r\n                  CloseKey;\r\n                end;\r\n              finally\r\n                Free;\r\n              end;\r\n            end;\r\n          end;\r\n          Result := Result + Format(' (Build %d)', &#x5B;dwBuildNumber and $FFFF]);\r\n        end;\r\n    end;\r\nend\r\nend;\r\n\r\nend.\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>{****************Delphi\u5e38\u7528\u83b7\u53d6\u7cfb\u7edf\u4fe1\u606f\u7684\u51fd\u6570********************* [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-403","post","type-post","status-publish","format-standard","hentry","category-code_related"],"_links":{"self":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts\/403","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/comments?post=403"}],"version-history":[{"count":1,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts\/403\/revisions"}],"predecessor-version":[{"id":4759,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/posts\/403\/revisions\/4759"}],"wp:attachment":[{"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/media?parent=403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/categories?post=403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kyle.ai\/blog\/wp-json\/wp\/v2\/tags?post=403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}