1717
1818#include < fcntl.h>
1919#ifdef WIN32
20- #include < windows.h>
21- #include < io.h>
20+ #include < algorithm>
2221#endif
2322
2423
@@ -34,7 +33,32 @@ SharedFiles::handlers_map::iterator SharedFiles::add_new_handler(
3433 return m_handlers.end ();
3534 }
3635
37- return m_handlers.insert ({ fileName, {fp, 0 } }).first ;
36+ #ifdef WIN32
37+ // replace invalid characters for a Win32 named object
38+ auto tmp = fileName;
39+ std::replace (tmp.begin (), tmp.end (), ' \\ ' , ' _' );
40+ std::replace (tmp.begin (), tmp.end (), ' /' , ' _' );
41+
42+ // use named mutex for multi-process locking support
43+ const auto mutexName = " Global\\ ModSecurity_" + tmp;
44+
45+ HANDLE hMutex = CreateMutex (NULL , FALSE , mutexName.c_str ());
46+ if (hMutex == NULL ) {
47+ error->assign (" Failed to create mutex for shared file: " + fileName);
48+ fclose (fp);
49+ return m_handlers.end ();
50+ }
51+ #endif
52+
53+ auto handler = handler_info {
54+ fp,
55+ #ifdef WIN32
56+ hMutex,
57+ #endif
58+ 0
59+ };
60+ // cppcheck-suppress resourceLeak ; false positive, fp is closed in SharedFiles::close
61+ return m_handlers.insert ({ fileName, handler }).first ;
3862}
3963
4064
@@ -69,6 +93,9 @@ void SharedFiles::close(const std::string& fileName) {
6993 if (it->second .cnt == 0 )
7094 {
7195 fclose (it->second .fp );
96+ #ifdef WIN32
97+ CloseHandle (it->second .hMutex );
98+ #endif
7299
73100 m_handlers.erase (it);
74101 }
@@ -92,9 +119,11 @@ bool SharedFiles::write(const std::string& fileName,
92119 lock.l_type = F_WRLCK;
93120 fcntl (fileno (it->second .fp ), F_SETLKW, &lock);
94121#else
95- auto handle = reinterpret_cast <HANDLE>(_get_osfhandle (fileno (it->second .fp )));
96- OVERLAPPED overlapped = { 0 };
97- ::LockFileEx (handle, LOCKFILE_EXCLUSIVE_LOCK, 0 , MAXDWORD, MAXDWORD, &overlapped);
122+ DWORD dwWaitResult = WaitForSingleObject (it->second .hMutex , INFINITE);
123+ if (dwWaitResult != WAIT_OBJECT_0) {
124+ error->assign (" couldn't lock shared file: " + fileName);
125+ return false ;
126+ }
98127#endif
99128
100129 auto wrote = fwrite (msg.c_str (), 1 , msg.size (), it->second .fp );
@@ -109,8 +138,7 @@ bool SharedFiles::write(const std::string& fileName,
109138 lock.l_type = F_UNLCK;
110139 fcntl (fileno (it->second .fp ), F_SETLKW, &lock);
111140#else
112- overlapped = { 0 };
113- ::UnlockFileEx (handle, 0 , MAXDWORD, MAXDWORD, &overlapped);
141+ ::ReleaseMutex (it->second.hMutex);
114142#endif
115143
116144 return ret;
0 commit comments