今日はMicrosoftのセキュリティアップデートの日です。
MS15-001
MS15-002
MS15-003
MS15-004
MS15-005
MS15-006
MS15-007
MS15-008
2015年1月14日
2015年1月9日
RAD Studio/Delphi/C++Builder XE7 Update 1 Beta hotfix for FireMonkey apps on Android 5.0 (Lollipop)
RAD Studio/Delphi/C++Builder XE7 Update 1のBeta hotfix for FireMonkey apps on Android 5.0 (Lollipop)がリリースされています。Marco CantuさんのLollipop Hotfix (Beta) for Delphi and C++ Builder XE7によると、Android 5 (Lollipop)でデフォルトとなったART KernelとのJNI Bridgeによる配列データの受け渡しの問題(RSP-9738など)に対応するとのことです。
30110 Beta hotfix for FireMonkey apps on Android 5.0 (Lollipop)
2015/01/14追記: RAD Studio XE7 Update 1とAndroid 5.0(Lollipop)との互換性の問題はQC上だとQC129208やQC129086が該当するものとのことです。高橋さん、いつも情報ありがとうございます。
30110 Beta hotfix for FireMonkey apps on Android 5.0 (Lollipop)
2015/01/14追記: RAD Studio XE7 Update 1とAndroid 5.0(Lollipop)との互換性の問題はQC上だとQC129208やQC129086が該当するものとのことです。高橋さん、いつも情報ありがとうございます。
InterBase XE3 Update 4 Hotfix 3
InterBase XE3 Update 4 Hotfix 3がリリースされています。バージョンは11.0.4.820となっています。
30112 InterBase XE3 Update 4 Hotfix 3 (11.0.4.820) for Windows
30112 InterBase XE3 Update 4 Hotfix 3 (11.0.4.820) for Windows
2015年1月6日
シリアルポートをフレンドリ名で列挙する
以前使用できるシリアルポートをレジストリから列挙する方法について書きましたが、今度はシリアルポートをそのフレンドリ名(デバイスマネージャ上で表示される表記)とともに列挙する方法です。
フレンドリ名の取得にはSetup APIを使用しますが、残念ながらDelphiにはSetup API関係の定義が含まれていない(C++Builderならsetupapi.hがあるのですが)ため、まずは必要なWin32APIと構造体を定義します。
→シリアルポートをフレンドリ名で列挙 (Gist)
フレンドリ名の取得にはSetup APIを使用しますが、残念ながらDelphiにはSetup API関係の定義が含まれていない(C++Builderならsetupapi.hがあるのですが)ため、まずは必要なWin32APIと構造体を定義します。
{ Setup APIs } type { HDEVINFO } HDEVINFO = THandle; {$EXTERNALSYM HDEVINFO} { SP_DEVINFO_DATA } SP_DEVINFO_DATA = packed record cbSize: DWORD; ClassGuid: TGUID; DevInst: DWORD; Reserved: ULONG_PTR; end; {$EXTERNALSYM SP_DEVINFO_DATA} const { Flags for SetupDiGetClassDevs } DIGCF_PRESENT = $00000002; {$EXTERNALSYM DIGCF_PRESENT} { Property for SetupDiGetDeviceRegistryProperty } SPDRP_DEVICEDESC = $00000000; {$EXTERNALSYM SPDRP_DEVICEDESC} SPDRP_FRIENDLYNAME = $0000000C; {$EXTERNALSYM SPDRP_FRIENDLYNAME} { Scope for SetupDiOpenDevRegKey } DICS_FLAG_GLOBAL = $00000001; {$EXTERNALSYM DICS_FLAG_GLOBAL} { KeyType for SetupDiOpenDevRegKey } DIREG_DEV = $00000001; {$EXTERNALSYM DIREG_DEV} { SetupDiClassGuidsFromName } function SetupDiClassGuidsFromName(const ClassName: PChar; ClassGuidList: PGUID; ClassGuidListSize: DWORD; var RequiredSize: DWORD): BOOL; stdcall; external 'SetupApi.dll' name {$IFDEF UNICODE} 'SetupDiClassGuidsFromNameW'; {$ELSE} 'SetupDiClassGuidsFromNameA'; {$ENDIF} {$EXTERNALSYM SetupDiClassGuidsFromName} { SetupDiGetClassDevs } function SetupDiGetClassDevs(ClassGuid: PGUID; const Enumerator: PChar; hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall; external 'SetupApi.dll' name {$IFDEF UNICODE} 'SetupDiGetClassDevsW'; {$ELSE} 'SetupDiGetClassDevsA'; {$ENDIF} {$EXTERNALSYM SetupDiGetClassDevs} { SetupDiDestroyDeviceInfoList } function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; stdcall; external 'SetupApi.dll' name 'SetupDiDestroyDeviceInfoList'; {$EXTERNALSYM SetupDiDestroyDeviceInfoList} { SetupDiEnumDeviceInfo } function SetupDiEnumDeviceInfo(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD; var DeviceInfoData: SP_DEVINFO_DATA): BOOL; stdcall; external 'SetupApi.dll' name 'SetupDiEnumDeviceInfo'; {$EXTERNALSYM SetupDiEnumDeviceInfo} { SetupDiGetDeviceRegistryProperty } function SetupDiGetDeviceRegistryProperty(DeviceInfoSet: HDEVINFO; const DeviceInfoData: SP_DEVINFO_DATA; Prop: DWORD; PropertyRegDataType: PDWORD; PropertyBuffer: Pointer; PropertyBufferSize: DWORD; var RequiredSize: DWORD): BOOL; stdcall; external 'SetupApi.dll' name {$IFDEF UNICODE} 'SetupDiGetDeviceRegistryPropertyW'; {$ELSE} 'SetupDiGetDeviceRegistryPropertyA'; {$ENDIF} {$EXTERNALSYM SetupDiGetDeviceRegistryProperty} { SetupDiOpenDevRegKey } function SetupDiOpenDevRegKey(DeviceInfoSet: HDEVINFO; var DeviceInfoData: SP_DEVINFO_DATA; Scope: DWORD; HwProfile: DWORD; KeyType: DWORD; samDesired: REGSAM): HKEY; stdcall; external 'SetupApi.dll' name 'SetupDiOpenDevRegKey'; {$EXTERNALSYM SetupDiOpenDevRegKey}これらを使用してシリアルポートをそのフレンドリ名とともに取得します。
function EnumSerialCommWithFriendlyName(const S: TStrings): Integer; var Guid: TGUID; Size: DWORD; hDevInf: HDEVINFO; Index: DWORD; DevInfoData: SP_DEVINFO_DATA; S1: String; hRegKey: HKEY; S2: String; RegType: DWORD; PortNo: Integer; begin Result := 0; Size := 0; if SetupDiClassGuidsFromName('Ports',@Guid,1,Size) = False then begin RaiseLastOSError; end; hDevInf := SetupDiGetClassDevs(@Guid,nil,0,DIGCF_PRESENT); if hDevInf = INVALID_HANDLE_VALUE then begin RaiseLastOSError; end; try Index := 0; while True do begin FillChar(DevInfoData,SizeOf(DevInfoData),0); DevInfoData.cbSize := SizeOf(DevInfoData); if SetupDiEnumDeviceInfo(hDevInf,Index,DevInfoData) = False then begin Break; end; SetupDiGetDeviceRegistryProperty(hDevInf,DevInfoData,SPDRP_FRIENDLYNAME, nil,nil,0,Size); SetLength(S1,(Size + SizeOf(Char)) div SizeOf(Char)); if SetupDiGetDeviceRegistryProperty(hDevInf,DevInfoData,SPDRP_FRIENDLYNAME, nil,PChar(S1),Size,Size) = True then begin SetLength(S1,StrLen(PChar(S1))); hRegKey := SetupDiOpenDevRegKey(hDevInf,DevInfoData,DICS_FLAG_GLOBAL,0,DIREG_DEV,KEY_READ); if hRegKey <> INVALID_HANDLE_VALUE then begin try if RegQueryInfoKey(hRegKey,nil,nil,nil,nil,nil,nil,nil,nil, @Size,nil,nil) = ERROR_SUCCESS then begin SetLength(S2,(Size + SizeOf(Char)) div SizeOf(Char)); if (RegQueryValueEx(hRegKey,'PortName',nil,@RegType,Pointer(PChar(S2)), @Size) = ERROR_SUCCESS) and (RegType = REG_SZ) then begin SetLength(S2,StrLen(PChar(S2))); if CompareText(Copy(S2,1,3),'COM') = 0 then begin if TryStrToInt(Copy(S2,4,Length(S2)),PortNo) = True then begin S.AddObject(S1,Pointer(PortNo)); if Result < PortNo then begin Result := PortNo; end; end; end; end; end; finally RegCloseKey(hRegKey); end; end; end; Index := Index + 1; end; finally SetupDiDestroyDeviceInfoList(hDevInf); end; end;手順ですが、まずSetupDiClassGuidsFromNameでデバイスインタフェースクラスが'Ports'のGUIDを取得し、そのGUIDを使用してSetupDiGetClassDevsで現在システムに認識されているDevice Information Setsを取得し、SetupDiEnumDeviceInfoでDevice Information Set一つずつの情報をSP_DEVINFO_DATAに取り出して、SetupDiGetDeviceRegistryPropertyでフレンドリ名を取得します。さらにSetupDiOpenDevRegKeyでデバイス固有情報の含まれるレジストリキー('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum'の下のデバイスごとのキーに含まれる'Device Parameters'キー)を開き、RegQueryValueExで'PortName'という名前でREG_SZの値のデータを文字列として取得し、'COM'で始まっていたらシリアルポートとしてフレンドリ名とともにパラメータ(S: TStrings)に格納します。全てのDevice Information Setをチェックし終わったらSetupDiDestroyDeviceInfoListでDevice Information Sets全体を解放します。 以前のものと同様に必ずしもポート番号順にはなっていないため、必要に応じて結果をソートしてください。
→シリアルポートをフレンドリ名で列挙 (Gist)
2015年1月1日
登録:
投稿 (Atom)