123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- unit mS4Utils;
- interface
- uses
- {$IFDEF _ScNet}
- S4Net;
- //Sense4Net;
- {$ELSE}
- //S4Single;
- Sense4;
- {$ENDIF}
- const
- // 197707074568224603070424
- Sense4DevPin = '19770707' + '45682246' + '03070424';
- Sense4UserPin = '45682246';
- Sense4AuthenPin = '19770707' + '03070424';
- Sense4OldDevPin = '12345678' + '12345678' + '12345678';
- Sense4OldUserPin = '12345678';
- Sense4OldAuthenPin = '12345678' + '12345678';
- function OpenSense(var s4Ctx: PSENSE4_CONTEXT): Boolean;
- procedure CloseSense(var s4Ctx: PSENSE4_CONTEXT);
- function WriteSenseData(s4Ctx: PSENSE4_CONTEXT; AFileID: string; APData: Pointer;
- ADataLength: Integer; AIsExe: Boolean; AIsUpdate: Boolean = False): Boolean;
- function WriteSenseFile(s4Ctx: PSENSE4_CONTEXT; AFileID: string; AFileName: string;
- AIsExe: Boolean; AIsUpdate: Boolean = False): Boolean;
- procedure SenseLEDOn(s4Ctx: PSENSE4_CONTEXT);
- procedure SenseLEDOff(s4Ctx: PSENSE4_CONTEXT);
- procedure SenseLEDFlash(s4Ctx: PSENSE4_CONTEXT);
- implementation
- uses
- Windows, Classes, SysUtils, Variants;
- var
- g_s4Ctx: PSENSE4_CONTEXT = nil;
- tmp_s4Ctx: PSENSE4_CONTEXT = nil;
- g_S4Opened: Boolean = False;
- // 深思4全局数据(特为网络版设计)
- {网络版应该一套软件占用一个授权,即三个应用程序只占用一个授权,
- 因此不管启动几个应用程序,都只能使用一次S4Open,
- 为此必须采用共享内存来存储深思4的数据,提供跨程序的调用。
- }
- type
- TGlobalS4Data = packed record
- // 深思网络锁引用计数
- SenseNetDogRefCount: Integer;
- // 深思加密锁数据
- SenseData: array [0..91] of Byte;
- end;
- PGlobalS4Data = ^TGlobalS4Data;
- const
- ScSense4ShareMemoryName = 'SmartCost_Sense4_Data_Handle';
- // 返回 0:函数调用失败;1:已存在共享内存对象;2:不存在共享内存对象
- function GetGlobalS4Ctx(var s4Ctx: PSENSE4_CONTEXT): Integer;
- var
- // 文件映射对象句柄
- ShareHandle: THandle;
- pData: PGlobalS4Data;
- SA: TSecurityAttributes;
- begin
- Result := 0;
- SA.nLength := SizeOf(SA);
- SA.lpSecurityDescriptor := nil;
- SA.bInheritHandle := False;
- ShareHandle := CreateFileMapping($FFFFFFFF, @SA, PAGE_READWRITE,
- 0, SizeOf(TGlobalS4Data), PChar(ScSense4ShareMemoryName));
- try
- // 已存在共享内存
- if GetLastError = ERROR_ALREADY_EXISTS then
- begin
- pData := MapViewOfFile(ShareHandle, File_MAP_WRITE, 0, 0, 0);
- try
- if pData <> nil then
- begin
- Inc(pData^.SenseNetDogRefCount);
- CopyMemory(s4Ctx, @(pData^.SenseData[0]), SizeOf(SENSE4_CONTEXT));
- Result := 1;
- end;
- finally
- // if pData <> nil then
- // UnmapViewOfFile(pData);
- end;
- end
- // 尚未存在共享内存
- else
- begin
- pData := MapViewOfFile(ShareHandle, File_MAP_WRITE, 0, 0, 0);
- try
- if pData <> nil then
- begin
- ZeroMemory(pData, SizeOf(TGlobalS4Data));
- pData^.SenseNetDogRefCount := 1;
- Result := 2;
- end;
- finally
- // if pData <> nil then
- // UnmapViewOfFile(pData);
- end;
- end;
- finally
- //CloseHandle(ShareHandle);
- end;
- end;
- function SetGlobalS4Ctx(var s4Ctx: PSENSE4_CONTEXT): Boolean;
- var
- // 文件映射对象句柄
- ShareHandle: THandle;
- pData: PGlobalS4Data;
- begin
- Result := False;
- ShareHandle := OpenFileMapping(FILE_MAP_WRITE, False, PChar(ScSense4ShareMemoryName));
- if ShareHandle <> Null then
- begin
- try
- pData := MapViewOfFile(ShareHandle, File_MAP_WRITE, 0, 0, 0);
- try
- if pData <> nil then
- begin
- CopyMemory(@(pData^.SenseData[0]), s4Ctx, SizeOf(SENSE4_CONTEXT));
- Result := True;
- end;
- finally
- if pData <> nil then
- UnmapViewOfFile(pData);
- end;
- finally
- CloseHandle(ShareHandle);
- end;
- end;
- end;
- function ReleaseGlobalS4Ctx(var s4Ctx: PSENSE4_CONTEXT): Boolean;
- var
- // 文件映射对象句柄
- ShareHandle: THandle;
- pData: PGlobalS4Data;
- begin
- Result := False;
- ShareHandle := OpenFileMapping(FILE_MAP_WRITE, False, PChar(ScSense4ShareMemoryName));
- if ShareHandle <> Null then
- begin
- try
- pData := MapViewOfFile(ShareHandle, File_MAP_WRITE, 0, 0, 0);
- try
- if pData <> nil then
- begin
- Dec(pData^.SenseNetDogRefCount);
- if pData^.SenseNetDogRefCount = 0 then
- S4Close(s4Ctx);
- Result := True;
- end;
- finally
- if pData <> nil then
- UnmapViewOfFile(pData);
- end;
- finally
- CloseHandle(ShareHandle);
- end;
- end;
- end;
- function OpenSense(var s4Ctx: PSENSE4_CONTEXT): Boolean;
- var
- CtxLength: Cardinal;
- begin
- Result := False;
- CtxLength := 0;
- {$IFDEF _ScNET}
- { 网络版为了控制节点数,必须保持OPEN状态,
- 而原来单机版的做法是OPEN后检查完就CLOSE;
- 好在OpenSense, CloseSense是成对调用,所以可做如下修改:
- 为兼容单机版的做法,在这里不每次打开,只是第一次打开,
- 另创建一个指针,并将传入的指针保存,
- 再把创建的指针传出去
- 在CloseSense时,不关闭,只把指针替换为原来传进来的指针}
- if g_s4Ctx = nil then
- begin
- S4Enum(nil, CtxLength);
- if CtxLength = 0 then Exit;
- New(g_s4Ctx);
- try
- if S4Enum(g_s4Ctx, CtxLength) = S4_SUCCESS then
- begin
- if S4Open(g_s4Ctx) = S4_SUCCESS then
- begin
- g_S4Opened := True;
- Result := True;
- end;
- end;
- { case GetGlobalS4Ctx(g_s4Ctx) of
- // 失败
- 0:
- Exit;
- // 已有其他版本程序打开锁
- 1:
- begin
- g_S4Opened := True;
- Result := True;
- end;
- // 首次打开锁
- 2:
- begin
- if S4Enum(g_s4Ctx, CtxLength) = S4_SUCCESS then
- begin
- if S4Open(g_s4Ctx) = S4_SUCCESS then
- begin
- g_S4Opened := True;
- SetGlobalS4Ctx(g_s4Ctx);
- Result := True;
- end;
- end;
- end;
- end;}
- except
- Result := False;
- end;
- end
- else
- Result := True;
- tmp_s4Ctx := s4Ctx;
- s4Ctx := g_s4Ctx;
- {$ELSE}
- S4Enum(nil, CtxLength);
- if CtxLength = 0 then Exit;
- try
- if S4Enum(s4Ctx, CtxLength) = S4_SUCCESS then
- begin
- if S4Open(s4Ctx) = S4_SUCCESS then
- begin
- Result := True;
- end;
- end;
- except
- Result := False;
- end;
- {$ENDIF}
- end;
- procedure CloseSense(var s4Ctx: PSENSE4_CONTEXT);
- begin
- {$IFDEF _ScNet}
- { 网络版为了控制节点数,必须保持OPEN状态,
- 而原来单机版的做法是OPEN后检查完就CLOSE;
- 为兼容单机版的做法,在这里不关闭,只是将OPEN时传入的指针再传出去
- 在程序关闭时再CLOSE}
- if Assigned(tmp_s4Ctx) then
- begin
- s4Ctx := tmp_s4Ctx;
- tmp_s4Ctx := nil;
- end
- else if s4Ctx = g_s4Ctx then
- begin
- s4Ctx := nil;
- New(s4Ctx);
- end;
- {$ELSE}
- S4Close(s4Ctx);
- {$ENDIF}
- end;
- function WriteSenseData(s4Ctx: PSENSE4_CONTEXT; AFileID: string; APData: Pointer;
- ADataLength: Integer; AIsExe: Boolean; AIsUpdate: Boolean): Boolean;
- var
- iBytes: Cardinal;
- iFileType: Byte;
- iFlag: Cardinal;
- iResult: Cardinal;
- begin
- {$IFDEF _ScNet}
- Result := True;
- {$ELSE}
- Result := False;
- if AIsExe then
- iFileType := S4_EXE_FILE
- else
- iFileType := S4_DATA_FILE;
- if AIsUpdate then
- iFlag := S4_UPDATE_FILE
- else
- iFlag := S4_CREATE_NEW;
- if S4VerifyPin(s4Ctx, Sense4DevPin, 24, S4_DEV_PIN) = S4_SUCCESS then
- begin
- iResult := S4WriteFile(s4Ctx, PChar(AFileID), 0, APData, ADataLength,
- ADataLength, iBytes, iFlag, iFileType);
- Result := iResult = S4_SUCCESS;
- end;
- {$ENDIF}
- end;
- function WriteSenseFile(s4Ctx: PSENSE4_CONTEXT; AFileID: string; AFileName: string;
- AIsExe: Boolean; AIsUpdate: Boolean): Boolean;
- var
- fsFile: TFileStream;
- pData: Pointer;
- begin
- fsFile := TFileStream.Create(AFileName, fmOpenRead);
- try
- pData := AllocMem(fsFile.Size);
- try
- ZeroMemory(pData, fsFile.Size);
- fsFile.Seek(0, soFromBeginning);
- fsFile.Read(pData^, fsFile.Size);
- Result := WriteSenseData(s4Ctx, AFileID, pData, fsFile.Size, AIsExe, AIsUpdate);
- finally
- FreeMem(pData);
- end;
- finally
- fsFile.Free;
- end;
- end;
- procedure SenseLEDOn(s4Ctx: PSENSE4_CONTEXT);
- var
- iReturn: Cardinal;
- begin
- {$IFNDEF _ScNet}
- S4Control(s4Ctx, S4_LED_UP, nil, 0, nil, 0, iReturn);
- {$ENDIF}
- end;
- procedure SenseLEDOff(s4Ctx: PSENSE4_CONTEXT);
- var
- iReturn: Cardinal;
- begin
- {$IFNDEF _ScNet}
- S4Control(s4Ctx, S4_LED_DOWN, nil, 0, nil, 0, iReturn);
- {$ENDIF}
- end;
- procedure SenseLEDFlash(s4Ctx: PSENSE4_CONTEXT);
- var
- iReturn: Cardinal;
- begin
- {$IFNDEF _ScNet}
- S4Control(s4Ctx, S4_LED_WINK, nil, 0, nil, 0, iReturn);
- {$ENDIF}
- end;
- initialization
- finalization
- if g_S4Opened and (g_s4Ctx <> nil) then
- //ReleaseGlobalS4Ctx(g_s4Ctx);
- S4Close(g_s4Ctx);
- end.
|