OSDN Git Service

Version1.86→1.00(新規)
[winbottle/winbottle.git] / sakurasuite / SakuraSeeker.pas
index 17ee3fc..33014d3 100644 (file)
@@ -1,13 +1,8 @@
-(*********************************************************
-
-  SakuraSeeker Component - Listups Existing Sakura.exe
-  (C)2001-2002 naruto/CANO-Lab  All Rights Reserved.
-
-  \95K\82¸\8eg\97p\8fð\8c\8f\82É\82µ\82½\82ª\82Á\82Ä\82¨\8eg\82¢\82­\82¾\82³\82¢\81B
-  \81\9a\82±\82Ì\83R\83\93\83|\81[\83l\83\93\83g\82ð\8eg\97p\82µ\82½\83v\83\8d\83O\83\89\83\80\82ð\8cö\8aJ\82·\82é\8fê\8d\87\82Í\81A
-\81@\81@\8dì\8eÒ\82É\88ê\95ñ\82·\82é\95K\97v\82ª\82 \82è\82Ü\82·\81B\8fÚ\82µ\82­\82Í\90à\96¾\8f\91\82ð\81B
-
-**********************************************************)
+{********************************************************}
+{ SakuraSeeker Component - Listups Existing SSTP Servers }
+{                                                        }
+{       Copyright (c) 2001-2003 naruto/CANO-Lab          }
+{********************************************************}
 
 unit SakuraSeeker;
 
@@ -21,6 +16,9 @@ type
 
   TSakuraSeeker = class;
 
+  TSakuraSeekerGetMutexNameEvent = procedure (Sender: TObject;
+    var Name: String) of object;
+
   TSakuraProcess = class(TObject)
   private
     FHash: TStringList;
@@ -37,10 +35,11 @@ type
     function GetDataAt(Index: integer): String;
     function GetCount: integer;
     function GetKeyAt(Index: integer): String;
+  protected
+    procedure AppendData(const Key, Value: String);
   public
     constructor Create(AOwner: TSakuraSeeker);
     destructor Destroy; override;
-    procedure AppendData(const Key, Value: String);
     property ProcessID: String read FProcessID write SetProcessID;
     property FMOName: String read FFMOName write SetFMOName;
     property HWnd: THandle read GetHWnd;
@@ -63,6 +62,8 @@ type
     FSourceResult: String;   //\8d¡\89ñ\82Ì\8eæ\93¾\8c\8b\89Ê\81B\94ä\8ar\97p
     FOnDetectResultChanged: TNotifyEvent;
     FFileMappingTarget: TStrings;
+    FOnGetMutexName: TSakuraSeekerGetMutexNameEvent;
+    FMutexPool: TStringList;
     function GetProcess(Index: integer): TSakuraProcess;
     procedure SetAutoDetect(const Value: boolean);
     function GetProcessByName(Name: String): TSakuraProcess;
@@ -72,12 +73,15 @@ type
     procedure SetOnDetectResultChanged(const Value: TNotifyEvent);
     procedure SetFileMappingTarget(const Value: TStrings);
     function GetProcessBySetName(Name: String): TSakuraProcess;
+    procedure SetOnGetMutexName(
+      const Value: TSakuraSeekerGetMutexNameEvent);
   protected
     { Protected \90é\8c¾ }
-    //FSakuraAPI: integer;
     procedure Loaded; override;
     procedure ClearList;
     procedure BeginDetectOne(const Target: String);
+    function GetMutexName(const Target: String): String;
+    function GetMutex(const Name: String): THandle;
   public
     { Public \90é\8c¾ }
     procedure BeginDetect;
@@ -95,6 +99,7 @@ type
     property OnAfterDetection: TNotifyEvent read FOnAfterDetection write SetOnAfterDetection;
     property OnDetectResultChanged: TNotifyEvent read FOnDetectResultChanged write SetOnDetectResultChanged;
     property FileMappingTarget: TStrings read FFileMappingTarget write SetFileMappingTarget;
+    property OnGetMutexName: TSakuraSeekerGetMutexNameEvent read FOnGetMutexName write SetOnGetMutexName;
   end;
 
 procedure Register;
@@ -137,7 +142,10 @@ end;
 
 function TSakuraProcess.GetDataAt(Index: integer): String;
 begin
-  Result := FHash.ValueFromIndex[Index];
+  if Index >= 0 then
+    Result := Copy(FHash[Index], Length(FHash.Names[Index]) + 2, High(integer))
+  else
+    Result := '';
 end;
 
 function TSakuraProcess.GetHWnd: THandle;
@@ -200,8 +208,8 @@ begin
 end;
 
 procedure TSakuraSeeker.BeginDetectOne(const Target: String);
-var MappingHandle: THandle;
-    P: pointer;
+var MappingHandle, Mutex: THandle;
+    P, PSaved: pointer;
     SourceStr, ID, Entry, Data: String;
     Size: integer;
     Strs: TStringList;
@@ -209,25 +217,38 @@ var MappingHandle: THandle;
     i, j: integer;
 begin
   //\83t\83@\83C\83\8b\83}\83b\83s\83\93\83O\83I\83u\83W\83F\83N\83g\82Ì\8eæ\93¾
-  P := nil; Strs := nil;
-  MappingHandle := OpenFileMapping(FILE_MAP_READ, false, PChar(Target));
+  PSaved := nil;
+  Strs := nil;
+  MappingHandle := 0;
+  
+  Mutex := GetMutex(GetMutexName(Target));
+  if Mutex = 0 then
+    raise ESakuraSeekerError.Create('Mutex\83n\83\93\83h\83\8b\82ð\8eæ\93¾\82Å\82«\82Ü\82¹\82ñ\82Å\82µ\82½');
+  if WaitForSingleObject(Mutex, 3000) = WAIT_TIMEOUT then
+    raise ESakuraSeekerError.Create('Mutex\93¯\8aú\83^\83C\83\80\83A\83E\83g');
   try
-    if MappingHandle = 0 then begin
-      SourceStr := '';
-    end else begin
-      P := MapViewOfFile(MappingHandle, FILE_MAP_READ, 0, 0, 0);
-      if P <> nil then begin
-        CopyMemory(@Size, P, SizeOf(integer));
-        Inc(PChar(P), SizeOf(integer));
-        SourceStr := PChar(P);
-        if Length(SourceStr) > Size then
-          raise ESakuraSeekerError.Create('FMO\82ð\8eæ\93¾\82Å\82«\82Ü\82¹\82ñ\82Å\82µ\82½');
+    MappingHandle := OpenFileMapping(FILE_MAP_READ, false, PChar(Target));
+    try
+      if MappingHandle = 0 then begin
+        SourceStr := '';
+      end else begin
+        PSaved := MapViewOfFile(MappingHandle, FILE_MAP_READ, 0, 0, 0);
+        P := PSaved;
+        if P <> nil then begin
+          CopyMemory(@Size, P, SizeOf(integer));
+          Inc(PChar(P), SizeOf(integer));
+          SourceStr := PChar(P);
+          if Length(SourceStr) > Size then
+            raise ESakuraSeekerError.Create('FMO\82ð\8eæ\93¾\82Å\82«\82Ü\82¹\82ñ\82Å\82µ\82½');
+        end;
       end;
+    finally
+      //\83I\83u\83W\83F\83N\83g\82Ì\94j\8aü
+      if PSaved <> nil then UnmapViewOfFile(PSaved);
     end;
   finally
-    //\83I\83u\83W\83F\83N\83g\82Ì\94j\8aü
-    if P <> nil then UnmapViewOfFile(P);
     if MappingHandle <> 0 then CloseHandle(MappingHandle);
+    ReleaseMutex(Mutex);
   end;
 
   //\83f\81[\83^\82ð\89ð\90Í
@@ -240,7 +261,6 @@ begin
         ID := Copy(Strs[i], 1, j-1);
         Entry := Copy(Strs[i], j+1, Pos(#1, Strs[i])-j-1);
         Data := Copy(Strs[i], Pos(#1, Strs[i])+1, High(integer));
-        //ShowMessage(ID + '/' + Entry + '/' + Data);
         Pro := GetProcessByID(ID);
         if Pro = nil then begin
           Pro := TSakuraProcess.Create(self);
@@ -270,15 +290,20 @@ begin
   FList := TObjectList.Create;
   FFileMappingTarget := TStringList.Create;
   FFileMappingTarget.Add('Sakura');
-  //
-  //FSakuraAPI := RegisterWindowMessage('Sakura');
+  FMutexPool := TStringList.Create;
 end;
 
 destructor TSakuraSeeker.Destroy;
+var i: integer;
 begin
   ClearList;
   FList.Free;
   FFileMappingTarget.Free;
+  for i := 0 to FMutexPool.Count-1 do
+  begin
+    CloseHandle(StrToInt(Copy(FMutexPool[i], Pos('=', FMutexPool[i])+1, High(integer))));
+  end;
+  FreeAndNil(FMutexPool);
 end;
 
 function TSakuraSeeker.GetCount: integer;
@@ -286,15 +311,34 @@ begin
   Result := FList.Count;
 end;
 
-function TSakuraSeeker.GetProcess(Index: integer): TSakuraProcess;
+function TSakuraSeeker.GetMutex(const Name: String): THandle;
 begin
-  try
-    Result := FList[Index] as TSakuraProcess;
-  except
-    raise ESakuraSeekerError.Create('\83\8a\83X\83g\82Ì\97L\8cø\94Í\88Í\82Ì\83C\83\93\83f\83b\83N\83X\82ª\8ew\92è\82³\82ê\82Ü\82µ\82½');
+  if FMutexPool.Values[Name] <> '' then
+  begin
+    Result := THandle(StrToInt(FMutexPool.Values[Name]));
+  end else
+  begin
+    Result := CreateMutex(nil, false, PChar(Name));
+    if Result <> 0 then
+      FMutexPool.Values[Name] := IntToStr(Result);
   end;
 end;
 
+function TSakuraSeeker.GetMutexName(const Target: String): String;
+begin
+  if Assigned(FOnGetMutexName) then
+  begin
+    Result := Target;
+    FOnGetMutexName(self, Result);
+  end else
+    Result := Target + 'FMO';
+end;
+
+function TSakuraSeeker.GetProcess(Index: integer): TSakuraProcess;
+begin
+  Result := FList[Index] as TSakuraProcess;
+end;
+
 function TSakuraSeeker.GetProcessByID(ID: String): TSakuraProcess;
 var i: integer;
 begin
@@ -332,7 +376,7 @@ begin
 end;
 
 function TSakuraSeeker.KillFMO(const TargetFMOName, TargetID: String): boolean;
-var MappingHandle: THandle;
+var MappingHandle, Mutex: THandle;
     P: pointer;
     SourceStr, ID: String;
     Size: integer;
@@ -342,44 +386,53 @@ begin
   //\83t\83@\83C\83\8b\83}\83b\83s\83\93\83O\83I\83u\83W\83F\83N\83g\82Ì\8eæ\93¾
   Result := false;
   P := nil;
-  MappingHandle := OpenFileMapping(FILE_MAP_WRITE, false, PChar(TargetFMOName));
-  if MappingHandle = 0 then Exit;
+  Mutex := GetMutex(GetMutexName(TargetFMOName));
+  if Mutex = 0 then
+    raise ESakuraSeekerError.Create('Mutex\83n\83\93\83h\83\8b\82ð\8eæ\93¾\82Å\82«\82Ü\82¹\82ñ\82Å\82µ\82½');
+  if WaitForSingleObject(Mutex, 3000) = WAIT_TIMEOUT then
+    raise ESakuraSeekerError.Create('Mutex\93¯\8aú\83^\83C\83\80\83A\83E\83g');
   try
-    SourceStr := '';
-    P := MapViewOfFile(MappingHandle, FILE_MAP_WRITE, 0, 0, 0);
-    if P <> nil then begin
-      CopyMemory(@Size, P, SizeOf(integer));
-      Inc(PChar(P), SizeOf(integer));
-      SourceStr := PChar(P);
-      if Length(SourceStr) > Size then
-        raise ESakuraSeekerError.Create('FMO\82ð\8eæ\93¾\82Å\82«\82Ü\82¹\82ñ\82Å\82µ\82½');
-    end;
-
-    //\83f\81[\83^\82ð\89ð\90Í
-    Strs := TStringList.Create;
+    MappingHandle := OpenFileMapping(FILE_MAP_WRITE, false, PChar(TargetFMOName));
+    if MappingHandle = 0 then Exit;
     try
-      Strs.Text := SourceStr;
-      for i := Strs.Count-1 downto 0 do begin
-        j := Pos('.', Strs[i]);
-        ID := Copy(Strs[i], 1, j-1);
-        if ID = TargetID then begin
-          Strs.Delete(i); // \97v\82ç\82È\82¢\83G\83\93\83g\83\8a\82ð\8dí\8f\9c
-          Result := true;
+      SourceStr := '';
+      P := MapViewOfFile(MappingHandle, FILE_MAP_WRITE, 0, 0, 0);
+      if P <> nil then begin
+        CopyMemory(@Size, P, SizeOf(integer));
+        Inc(PChar(P), SizeOf(integer));
+        SourceStr := PChar(P);
+        if Length(SourceStr) > Size then
+          raise ESakuraSeekerError.Create('FMO\82ð\8eæ\93¾\82Å\82«\82Ü\82¹\82ñ\82Å\82µ\82½');
+      end;
+
+      //\83f\81[\83^\82ð\89ð\90Í
+      Strs := TStringList.Create;
+      try
+        Strs.Text := SourceStr;
+        for i := Strs.Count-1 downto 0 do begin
+          j := Pos('.', Strs[i]);
+          ID := Copy(Strs[i], 1, j-1);
+          if ID = TargetID then begin
+            Strs.Delete(i); // \97v\82ç\82È\82¢\83G\83\93\83g\83\8a\82ð\8dí\8f\9c
+            Result := true;
+          end;
         end;
+        SourceStr := Strs.Text;
+      finally
+        Strs.Free;
       end;
-      SourceStr := Strs.Text;
-    finally
-      Strs.Free;
-    end;
 
-    if Result then begin
-      CopyMemory(P, PChar(SourceStr), Length(SourceStr)+1);
-      Dec(PChar(P), SizeOf(integer));
+      if Result then begin
+        CopyMemory(P, PChar(SourceStr), Length(SourceStr)+1);
+        Dec(PChar(P), SizeOf(integer));
+      end;
+    finally
+      //\83I\83u\83W\83F\83N\83g\82Ì\94j\8aü
+      if P <> nil then UnmapViewOfFile(P);
+      CloseHandle(MappingHandle);
     end;
   finally
-    //\83I\83u\83W\83F\83N\83g\82Ì\94j\8aü
-    if P <> nil then UnmapViewOfFile(P);
-    CloseHandle(MappingHandle);
+    ReleaseMutex(Mutex);
   end;
 end;
 
@@ -410,5 +463,11 @@ begin
   FOnDetectResultChanged := Value;
 end;
 
+procedure TSakuraSeeker.SetOnGetMutexName(
+  const Value: TSakuraSeekerGetMutexNameEvent);
+begin
+  FOnGetMutexName := Value;
+end;
+
 end.
  
\ No newline at end of file