278 lines
7.2 KiB
Plaintext
278 lines
7.2 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ ManagerFixedDisk }
|
|
{ }
|
|
{ Copyright (C) 2023 kku }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit ManagerFixedDisk;
|
|
|
|
interface
|
|
|
|
uses
|
|
Tocsg.Obj, System.SysUtils, Tocsg.Disk, System.Classes, Tocsg.Driver,
|
|
Winapi.Windows, System.Generics.Collections;
|
|
|
|
type
|
|
TDetectDiskType = (ddtAdd, ddtRemove);
|
|
PDetectDisk = ^TDetectDisk;
|
|
TDetectDisk = record
|
|
DType: TDetectDiskType;
|
|
DInfo: TDriveInfo;
|
|
end;
|
|
TDetectDiskList = class(TList<PDetectDisk>)
|
|
protected
|
|
procedure Notify(const Item: PDetectDisk; Action: TCollectionNotification); override;
|
|
end;
|
|
|
|
TDriveInfoList = class(TList<PDriveInfo>)
|
|
protected
|
|
procedure Notify(const Item: PDriveInfo; Action: TCollectionNotification); override;
|
|
public
|
|
function GetDriveInfo(sFriName, sSrial: String; llSize: LONGLONG): PDriveInfo;
|
|
function GetDriveInfo_Def(sSrial, sClassGuid: String): PDriveInfo;
|
|
end;
|
|
|
|
TManagerFixedDisk = class(TTgObject)
|
|
private
|
|
DrvList_: TDriveInfoList;
|
|
public
|
|
Constructor Create;
|
|
Destructor Destroy; override;
|
|
|
|
function DetectChangeDisk: TDetectDiskList;
|
|
|
|
procedure Save;
|
|
procedure Load;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Tocsg.Exception, Tocsg.Safe, superobject, Tocsg.Json, Tocsg.Path,
|
|
GlobalDefine;
|
|
|
|
{ TDetectDiskList }
|
|
|
|
procedure TDetectDiskList.Notify(const Item: PDetectDisk; Action: TCollectionNotification);
|
|
begin
|
|
if Action = cnRemoved then
|
|
Dispose(Item);
|
|
end;
|
|
|
|
{ TDriveInfoList }
|
|
|
|
procedure TDriveInfoList.Notify(const Item: PDriveInfo; Action: TCollectionNotification);
|
|
begin
|
|
if Action = cnRemoved then
|
|
Dispose(Item);
|
|
end;
|
|
|
|
// OS 업데이트등의 이유로 sFriName, llSize가 빈값으로 잡히는 경우가 있다... 25_0319 14:12:28 kku
|
|
// 이전 디스크 목록을 비교하기 위해서는 적합하지 않음
|
|
// 이걸로 다시 사용 25_0826 14:58:41 kku
|
|
function TDriveInfoList.GetDriveInfo(sFriName, sSrial: String; llSize: LONGLONG): PDriveInfo;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
for i := 0 to Count - 1 do
|
|
begin
|
|
if (CompareText(Items[i].sFriendlyName, sFriName) = 0) and
|
|
(CompareText(Items[i].sSerial, sSrial) = 0) and
|
|
(Items[i].llSize = llSize) then
|
|
begin
|
|
Result := Items[i];
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// 같은 제조사에서 나온 디스크는 sSrial, sClassGuid 값이 같다...
|
|
// 이걸로 사용할 수 없음. 25_0826 14:57:58 kku
|
|
function TDriveInfoList.GetDriveInfo_Def(sSrial, sClassGuid: String): PDriveInfo;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
for i := 0 to Count - 1 do
|
|
begin
|
|
if (CompareText(Items[i].sSerial, sSrial) = 0) and
|
|
(CompareText(Items[i].sClassGuid, sClassGuid) = 0) then
|
|
begin
|
|
Result := Items[i];
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TManagerFixedDisk }
|
|
|
|
Constructor TManagerFixedDisk.Create;
|
|
begin
|
|
Inherited Create;
|
|
DrvList_ := TDriveInfoList.Create;
|
|
Load;
|
|
end;
|
|
|
|
Destructor TManagerFixedDisk.Destroy;
|
|
begin
|
|
if DrvList_ <> nil then
|
|
FreeAndNil(DrvList_);
|
|
Inherited;
|
|
end;
|
|
|
|
function TManagerFixedDisk.DetectChangeDisk: TDetectDiskList;
|
|
var
|
|
DrvLtList: TDevPathLetterList;
|
|
ChkList: TDriveInfoList;
|
|
pEnt, pChkEnt: PDriveInfo;
|
|
pDtEnt: PDetectDisk;
|
|
i: Integer;
|
|
bFirst, bUpdate: Boolean;
|
|
sDrive: String;
|
|
begin
|
|
try
|
|
bUpdate := false;
|
|
bFirst := DrvList_.Count = 0;
|
|
Result := TDetectDiskList.Create;
|
|
|
|
Guard(DrvLtList, TDevPathLetterList.Create);
|
|
if GetDrivesDevPathLetterList(DrvLtList) = 0 then
|
|
begin
|
|
// _Trace('Fail .. DetectChangeDisk() .. 1', 9);
|
|
exit;
|
|
end;
|
|
|
|
ChkList := TDriveInfoList.Create;
|
|
for i := 0 to DrvLtList.Count - 1 do
|
|
begin
|
|
New(pEnt);
|
|
sDrive := DrvLtList[i].cLetter + ':\';
|
|
GetDriveDetail(sDrive, pEnt, true);
|
|
if not bFirst and (pEnt.sFriendlyName = '') then
|
|
begin
|
|
// 업데이트, 윈도우 시작 직후 등 장치 정보를 제대로 가져오지 못하는 경우가 있다.
|
|
// 장치 이름이 없고 기존 정보에 시리얼등이 있을 경우 걸러준다 25_0826 15:09:10 kku
|
|
pChkEnt := DrvList_.GetDriveInfo_Def(pEnt.sSerial, pEnt.sClassGuid);
|
|
if (pChkEnt <> nil) and (pChkEnt.sFriendlyName <> '') then
|
|
begin
|
|
_Trace('Fail .. DetectChangeDisk() .. Empty FriName ... Serial=%s', [pEnt.sSerial], 1);
|
|
Dispose(pEnt);
|
|
FreeAndNil(ChkList);
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
if Pos('USB', UpperCase(pEnt.sSerial)) = 1 then // 이동식 제외
|
|
begin
|
|
Dispose(pEnt);
|
|
continue;
|
|
end;
|
|
|
|
ChkList.Add(pEnt);
|
|
end;
|
|
|
|
// 추가된 디스크 확인
|
|
for i := 0 to ChkList.Count - 1 do
|
|
begin
|
|
if not bFirst and
|
|
(DrvList_.GetDriveInfo(ChkList[i].sFriendlyName, ChkList[i].sSerial, ChkList[i].llSize) = nil) then
|
|
begin
|
|
New(pDtEnt);
|
|
pDtEnt.DType := ddtAdd;
|
|
pDtEnt.DInfo := ChkList[i]^;
|
|
Result.Add(pDtEnt);
|
|
bUpdate := true;
|
|
|
|
_Trace('고정 디스크 추가 : Drive=%s, Name=%s', [pDtEnt.DInfo.sDrive, pDtEnt.DInfo.sFriendlyName], 3);
|
|
end;
|
|
end;
|
|
|
|
// 제거된 디스크 확인
|
|
for i := 0 to DrvList_.Count - 1 do
|
|
begin
|
|
if not bFirst and
|
|
(ChkList.GetDriveInfo(DrvList_[i].sFriendlyName, DrvList_[i].sSerial, DrvList_[i].llSize) = nil) then
|
|
begin
|
|
New(pDtEnt);
|
|
pDtEnt.DType := ddtRemove;
|
|
pDtEnt.DInfo := DrvList_[i]^;
|
|
Result.Add(pDtEnt);
|
|
bUpdate := true;
|
|
|
|
_Trace('고정 디스크 제거 : Drive=%s, Name=%s', [pDtEnt.DInfo.sDrive, pDtEnt.DInfo.sFriendlyName], 3);
|
|
end;
|
|
end;
|
|
|
|
if bUpdate then
|
|
begin
|
|
if DrvList_ <> nil then
|
|
FreeAndNil(DrvList_);
|
|
DrvList_ := ChkList;
|
|
|
|
Save;
|
|
_Trace('고정 디스크 정보 저장', 3);
|
|
end else
|
|
FreeAndNil(ChkList);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. DetectChangeDisk()');
|
|
end;
|
|
end;
|
|
|
|
procedure TManagerFixedDisk.Save;
|
|
var
|
|
O, OA: ISuperObject;
|
|
i: Integer;
|
|
begin
|
|
try
|
|
OA := TSuperObject.Create(stArray);
|
|
for i := 0 to DrvList_.Count - 1 do
|
|
OA.AsArray.Add(TTgJson.ValueToJsonObject<TDriveInfo>(DrvList_[i]^));
|
|
|
|
O := SO;
|
|
O.O['List'] := OA;
|
|
SaveJsonObjToEncFile(O, GetRunExePathDir + DIR_CONF + DAT_FIXDISK, PASS_STRENC);
|
|
// SaveJsonObjToFile(O, 'C:\diskInfo.json')
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. Save()');
|
|
end;
|
|
end;
|
|
|
|
procedure TManagerFixedDisk.Load;
|
|
var
|
|
sPath: String;
|
|
O: ISuperObject;
|
|
i: Integer;
|
|
pEnt: PDriveInfo;
|
|
begin
|
|
try
|
|
DrvList_.Clear;
|
|
|
|
sPath := GetRunExePathDir + DIR_CONF + DAT_FIXDISK;
|
|
if not FileExists(sPath) then
|
|
exit;
|
|
|
|
if not LoadJsonObjFromEncFile(O, sPath, PASS_STRENC) then
|
|
exit;
|
|
|
|
if (O.O['List'] = nil) or (O.O['List'].DataType <> stArray) then
|
|
exit;
|
|
|
|
for i := 0 to O.A['List'].Length - 1 do
|
|
begin
|
|
New(pEnt);
|
|
pEnt^ := TTgJson.GetDataAsType<TDriveInfo>(O.A['List'].O[i]);
|
|
DrvList_.Add(pEnt);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. Load()');
|
|
end;
|
|
end;
|
|
|
|
end.
|