Reference: Memory Objects (External site)
Currently, this specification is heavily dependent on the Windows specification and is not intended for implementation on other operating systems.
Since shared memory and Mutex itself exist in other OSes, it would be desirable to define a separate specification.
If the specifications are decided, we will consider publishing them separately, so please contact Ukadoc Project.
To indicate that the baseware is running, SSP holds a Mutex named "ssp", and Materia and CROW hold a Mutex named "sakura".
By checking for the presence of this named Mutex, you can determine whether it is running or not at a low cost.
The state of the Mutex itself is not determined, and there is no need to check whether or not it is in a signal state.
HANDLE hmutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"ssp");
if ( hmutex ) {
// Exists
CloseHandle(hmutex);
}
else {
// Does not exist
}
All baseware maintains a named file mapping object (FMO) while running.
By reading this inter-process shared memory, the running ghost can be obtained at relatively low cost.
To avoid incomplete information while writing, exclusive control is performed by Mutex for FMO. Please check these together.
Saura: OS dependent, Shift JIS on Japanese OS
SakuraUnicode: Fixed to UTF-8 [SSP 2.5.26 or later]
The first 4 bytes (bytes 0-3) indicate the size of the allocated FMO.
This is not the length of the information being written, but is a fixed value that indicates the allocated size of the FMO itself.
The value is currently fixed at 0x00010000 in little-endian, or 64kb.
To ensure compatibility with other programs, size changes are not currently considered.
The 4th and subsequent bytes are the main body of the FMO data. This will be in the following format.
(32-byte unique ID).(key name)[\1]value[\r\n]
[\1] is byte value 1, [\r\n] is CR_LF (line feed).
This format is repeated on multiple lines.
The end of the data is a byte value of 0, the same as for a C string.
Hence, the maximum size available for the data body is 65531 bytes (65536 - 4 - 1).
If you need to write to FOM and are about to exceed the size limit, be careful not to write incomplete information.
If the size is likely to be exceeded, it is preferable not to write a whole set of data. Even if this is not possible, do not end in the middle of a single line.
ssp_fmo_header_00004468_000f0dea.path[\1]D:\ssp\
ssp_fmo_header_00004468_000f0dea.hwnd[\1]986602
ssp_fmo_header_00004468_000f0dea.name[\1]Lache
ssp_fmo_header_00004468_000f0dea.keroname[\1]Tisse
ssp_fmo_header_00004468_000f0dea.sakura.surface[\1]0
ssp_fmo_header_00004468_000f0dea.kero.surface[\1]10
ssp_fmo_header_00004468_000f0dea.kerohwnd[\1]1052114
ssp_fmo_header_00004468_000f0dea.hwndlist[\1]986602,1052114
ssp_fmo_header_00004468_000f0dea.ghostpath[\1]D:\ssp\ghost\DE10_3001\
ssp_fmo_header_00004468_00120da6.path[\1]D:\ssp\
ssp_fmo_header_00004468_00120da6.hwnd[\1]1183142
ssp_fmo_header_00004468_00120da6.name[\1]Emily
ssp_fmo_header_00004468_00120da6.keroname[\1]Teddy
ssp_fmo_header_00004468_00120da6.sakura.surface[\1]20
ssp_fmo_header_00004468_00120da6.kero.surface[\1]10
ssp_fmo_header_00004468_00120da6.kerohwnd[\1]1117626
ssp_fmo_header_00004468_00120da6.hwndlist[\1]1183142,1117626,921002,2035340,658950
ssp_fmo_header_00004468_00120da6.ghostpath[\1]D:\ssp\ghost\emily4\
This is a unique unique ID that indicates one group of ghosts. You must choose a string that is unique, at least within the FMO.
In many cases, some unique information is combined to obtain an MD5 hash or a combination of HWND (window handle).
Although the length is not specified in the Materia standard, it should be a fixed length of 32 bytes for compatibility.
A key indicating the type of information and the information body. It is as follows.
Since FMO itself does not have an exclusive control mechanism, a separate Mutex is maintained to avoid write/read conflicts.
The name will be FMO name + "FMO". For example:
FMO = Sakura : Mutex = SakuraFMO
FMO = SakuraUnicode : Mutex = SakuraUnicodeFMO
The determination of signal and non-signal status is important here.
When reading or writing, be sure to use WaitForSingleObject or an equivalent wait function to acquire ownership, and ReleaseMutex to release ownership when finished.
Old baseware may not support Mutex for FMO, so please do not generate an error if you fail to obtain Mutex.
In this case, please keep in mind the possibility of obtaining an incomplete FMO during writing, and write code that can handle this as safely as possible.
//Use CreateMutex instead for apps that should be retained, such as baseware
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"SakuraFMO");
//Some baseware is not compatible with Mutex for FMO, so simply skip if not found
bool isWaitSuccess = true;
if ( hMutex ) {
//If you wait with INFINITE, it will wait forever and the GUI will freeze, so be creative accordingly
DWORD result = WaitForSingleObject(hMutex,INFINITE);
if ( result != WAIT_OBJECT_0 ) {
isWaitSuccess = false;
}
}
if ( isWaitSuccess ) {
//Apps that should be retained use CreateMutex instead
HANDLE hFMO = OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,"Sakura");
if ( hFMO ) {
char *pDataStart = static_cast<char*>(MapViewOfFile(hFMO,FILE_MAP_ALL_ACCESS,0,0,0));
if ( pDataStart ) {
//The 4 bytes at the head are the FMO maximum size.
//Note that this is different from string termination (zero termination of C strings).
unsigned long length = *reinterpret_cast<unsigned long*>(pDataStart);
char *pData = pDataStart;
pData += 4;
//****************************************
//Do something with pData and length here
//****************************************
//Release MapViewOfFile
UnmapViewOfFile(pDataStart);
}
//Open FMO handle
//Keep apps that should be retained, such as baseware, without opening them
CloseHandle(hFMO);
}
}
if ( hMutex ) {
if ( isWaitSuccess ) {
//WaitForSingleObject causes Mutex to go to non-signal state, return to original state (Release)
ReleaseMutex(hMutex);
}
//Finally, the Mutex handle is also released since it is not needed
//Keep apps that should be retained, such as baseware, without opening them
CloseHandle(hMutex);
}