| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 | unit DbS4Utils;interfaceuses  {$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);implementationuses  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;initializationfinalization  if g_S4Opened and (g_s4Ctx <> nil) then    //ReleaseGlobalS4Ctx(g_s4Ctx);    S4Close(g_s4Ctx);end.
 |