Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /*****************************
7 Windows implementation of probes, using xperf
8 *****************************/
9 #include <windows.h>
10 #include <wmistr.h>
11 #include <evntrace.h>
13 #include "perfprobe.h"
14 #include "nsAutoPtr.h"
16 namespace mozilla {
17 namespace probes {
19 #if defined(MOZ_LOGGING)
20 static PRLogModuleInfo *
21 GetProbeLog()
22 {
23 static PRLogModuleInfo *sLog;
24 if (!sLog)
25 sLog = PR_NewLogModule("SysProbe");
26 return sLog;
27 }
28 #define LOG(x) PR_LOG(GetProbeLog(), PR_LOG_DEBUG, x)
29 #else
30 #define LOG(x)
31 #endif
33 //Utility function
34 GUID CID_to_GUID(const nsCID &aCID)
35 {
36 GUID result;
37 result.Data1 = aCID.m0;
38 result.Data2 = aCID.m1;
39 result.Data3 = aCID.m2;
40 for (int i = 0; i < 8; ++i)
41 result.Data4[i] = aCID.m3[i];
42 return result;
43 }
47 // Implementation of Probe
49 Probe::Probe(const nsCID &aGUID,
50 const nsACString &aName,
51 ProbeManager *aManager)
52 : mGUID(CID_to_GUID(aGUID))
53 , mName(aName)
54 , mManager(aManager)
55 {
56 }
58 nsresult Probe::Trigger()
59 {
60 if (!(mManager->mIsActive)) {
61 //Do not trigger if there is no session
62 return NS_OK;
63 }
65 _EVENT_TRACE_HEADER event;
66 ZeroMemory(&event, sizeof(event));
67 event.Size = sizeof(event);
68 event.Flags = WNODE_FLAG_TRACED_GUID ;
69 event.Guid = (const GUID)mGUID;
70 event.Class.Type = 1;
71 event.Class.Version = 0;
72 event.Class.Level = TRACE_LEVEL_INFORMATION;
74 ULONG result = TraceEvent(mManager->mSessionHandle, &event);
76 LOG(("Probes: Triggered %s, %s, %ld",
77 mName.Data(),
78 result==ERROR_SUCCESS ? "success":"failure",
79 result));
81 nsresult rv;
82 switch(result)
83 {
84 case ERROR_SUCCESS: rv = NS_OK; break;
85 case ERROR_INVALID_FLAG_NUMBER:
86 case ERROR_MORE_DATA:
87 case ERROR_INVALID_PARAMETER: rv = NS_ERROR_INVALID_ARG; break;
88 case ERROR_INVALID_HANDLE: rv = NS_ERROR_FAILURE; break;
89 case ERROR_NOT_ENOUGH_MEMORY:
90 case ERROR_OUTOFMEMORY: rv = NS_ERROR_OUT_OF_MEMORY; break;
91 default: rv = NS_ERROR_UNEXPECTED;
92 }
93 return rv;
94 }
97 // Implementation of ProbeManager
99 ProbeManager::~ProbeManager()
100 {
101 //If the manager goes out of scope, stop the session.
102 if (mIsActive && mRegistrationHandle) {
103 StopSession();
104 }
105 }
107 ProbeManager::ProbeManager(const nsCID &aApplicationUID,
108 const nsACString &aApplicationName)
109 : mApplicationUID(aApplicationUID)
110 , mApplicationName(aApplicationName)
111 , mSessionHandle(0)
112 , mRegistrationHandle(0)
113 {
114 #if defined(MOZ_LOGGING)
115 char cidStr[NSID_LENGTH];
116 aApplicationUID.ToProvidedString(cidStr);
117 LOG(("ProbeManager::Init for application %s, %s",
118 aApplicationName.Data(), cidStr));
119 #endif
120 }
122 //Note: The Windows API is just a little bit scary there.
123 //The only way to obtain the session handle is to
124 //- ignore the session handle obtained from RegisterTraceGuids
125 //- pass a callback
126 //- in that callback, request the session handle through
127 // GetTraceLoggerHandle and some opaque value received by the callback
129 ULONG WINAPI ControlCallback(
130 WMIDPREQUESTCODE RequestCode,
131 PVOID Context,
132 ULONG *Reserved,
133 PVOID Buffer
134 )
135 {
136 ProbeManager* context = (ProbeManager*)Context;
137 switch(RequestCode)
138 {
139 case WMI_ENABLE_EVENTS:
140 {
141 context->mIsActive = true;
142 TRACEHANDLE sessionHandle = GetTraceLoggerHandle(Buffer);
143 //Note: We only accept one handle
144 if ((HANDLE)sessionHandle == INVALID_HANDLE_VALUE) {
145 ULONG result = GetLastError();
146 LOG(("Probes: ControlCallback failed, %ul", result));
147 return result;
148 } else if (context->mIsActive && context->mSessionHandle
149 && context->mSessionHandle != sessionHandle) {
150 LOG(("Probes: Can only handle one context at a time, "
151 "ignoring activation"));
152 return ERROR_SUCCESS;
153 } else {
154 context->mSessionHandle = sessionHandle;
155 LOG(("Probes: ControlCallback activated"));
156 return ERROR_SUCCESS;
157 }
158 }
160 case WMI_DISABLE_EVENTS:
161 context->mIsActive = false;
162 context->mSessionHandle = 0;
163 LOG(("Probes: ControlCallback deactivated"));
164 return ERROR_SUCCESS;
166 default:
167 LOG(("Probes: ControlCallback does not know what to do with %d",
168 RequestCode));
169 return ERROR_INVALID_PARAMETER;
170 }
171 }
173 already_AddRefed<Probe> ProbeManager::GetProbe(const nsCID &eventUID,
174 const nsACString &eventName)
175 {
176 nsRefPtr<Probe> result(new Probe(eventUID, eventName, this));
177 mAllProbes.AppendElement(result);
178 return result.forget();
179 }
181 nsresult ProbeManager::StartSession()
182 {
183 return StartSession(mAllProbes);
184 }
186 nsresult ProbeManager::StartSession(nsTArray<nsRefPtr<Probe>> &aProbes)
187 {
188 const size_t probesCount = aProbes.Length();
189 _TRACE_GUID_REGISTRATION* probes = new _TRACE_GUID_REGISTRATION[probesCount];
190 for (unsigned int i = 0; i < probesCount; ++i) {
191 const Probe *probe = aProbes[i];
192 const Probe *probeX = static_cast<const Probe*>(probe);
193 probes[i].Guid = (LPCGUID)&(probeX->mGUID);
194 }
195 ULONG result =
196 RegisterTraceGuids(&ControlCallback
197 /*RequestAddress: Sets mSessions appropriately.*/,
198 this
199 /*RequestContext: Passed to ControlCallback*/,
200 (LPGUID)&mApplicationUID
201 /*ControlGuid: Tracing GUID
202 the cast comes from MSDN examples*/,
203 probesCount
204 /*GuidCount: Number of probes*/,
205 probes
206 /*TraceGuidReg: Probes registration*/,
207 nullptr
208 /*MofImagePath: Must be nullptr, says MSDN*/,
209 nullptr
210 /*MofResourceName:Must be nullptr, says MSDN*/,
211 &mRegistrationHandle
212 /*RegistrationHandle: Handler.
213 used only for unregistration*/
214 );
215 delete[] probes;
216 if (NS_WARN_IF(result != ERROR_SUCCESS))
217 return NS_ERROR_UNEXPECTED;
218 return NS_OK;
219 }
221 nsresult ProbeManager::StopSession()
222 {
223 LOG(("Probes: Stopping measures"));
224 if (mSessionHandle != 0) {
225 ULONG result = UnregisterTraceGuids(mSessionHandle);
226 mSessionHandle = 0;
227 if (result != ERROR_SUCCESS) {
228 return NS_ERROR_INVALID_ARG;
229 }
230 }
231 return NS_OK;
232 }
235 }
236 }