Bug 1046841 - Convert xpcom/build/ to Gecko style. r=froydnj

This commit is contained in:
Birunthan Mohanathas 2014-08-13 11:45:37 -07:00
parent 6ca1a89029
commit 867507f7fd
30 changed files with 2186 additions and 2130 deletions

View File

@ -17,70 +17,79 @@
namespace mozilla {
class BinaryPath {
class BinaryPath
{
public:
#ifdef XP_WIN
static nsresult Get(const char *argv0, char aResult[MAXPATHLEN])
static nsresult Get(const char* argv0, char aResult[MAXPATHLEN])
{
wchar_t wide_path[MAXPATHLEN];
nsresult rv = GetW(argv0, wide_path);
if (NS_FAILED(rv))
if (NS_FAILED(rv)) {
return rv;
}
WideCharToMultiByte(CP_UTF8, 0, wide_path, -1,
aResult, MAXPATHLEN, nullptr, nullptr);
return NS_OK;
}
private:
static nsresult GetW(const char *argv0, wchar_t aResult[MAXPATHLEN])
static nsresult GetW(const char* argv0, wchar_t aResult[MAXPATHLEN])
{
if (::GetModuleFileNameW(0, aResult, MAXPATHLEN))
if (::GetModuleFileNameW(0, aResult, MAXPATHLEN)) {
return NS_OK;
}
return NS_ERROR_FAILURE;
}
#elif defined(XP_MACOSX)
static nsresult Get(const char *argv0, char aResult[MAXPATHLEN])
static nsresult Get(const char* argv0, char aResult[MAXPATHLEN])
{
// Works even if we're not bundled.
CFBundleRef appBundle = CFBundleGetMainBundle();
if (!appBundle)
if (!appBundle) {
return NS_ERROR_FAILURE;
}
CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle);
if (!executableURL)
if (!executableURL) {
return NS_ERROR_FAILURE;
}
nsresult rv;
if (CFURLGetFileSystemRepresentation(executableURL, false, (UInt8 *)aResult, MAXPATHLEN))
if (CFURLGetFileSystemRepresentation(executableURL, false, (UInt8*)aResult,
MAXPATHLEN)) {
rv = NS_OK;
else
} else {
rv = NS_ERROR_FAILURE;
}
CFRelease(executableURL);
return rv;
}
#elif defined(ANDROID)
static nsresult Get(const char *argv0, char aResult[MAXPATHLEN])
static nsresult Get(const char* argv0, char aResult[MAXPATHLEN])
{
// On Android, we use the GRE_HOME variable that is set by the Java
// bootstrap code.
const char *greHome = getenv("GRE_HOME");
const char* greHome = getenv("GRE_HOME");
#if defined(MOZ_WIDGET_GONK)
if (!greHome)
if (!greHome) {
greHome = "/system/b2g";
}
#endif
if (!greHome)
if (!greHome) {
return NS_ERROR_FAILURE;
}
snprintf(aResult, MAXPATHLEN, "%s/%s", greHome, "dummy");
aResult[MAXPATHLEN-1] = '\0';
aResult[MAXPATHLEN - 1] = '\0';
return NS_OK;
}
#elif defined(XP_UNIX)
static nsresult Get(const char *argv0, char aResult[MAXPATHLEN])
static nsresult Get(const char* aArgv0, char aResult[MAXPATHLEN])
{
struct stat fileStat;
// on unix, there is no official way to get the path of the current binary.
@ -91,23 +100,26 @@ private:
// PATH. Only do so if argv[0] looks like a path (contains a /).
// 2) manually walk through the PATH and look for ourself
// 3) give up
if (strchr(argv0, '/') && realpath(argv0, aResult) &&
stat(aResult, &fileStat) == 0)
if (strchr(aArgv0, '/') && realpath(aArgv0, aResult) &&
stat(aResult, &fileStat) == 0) {
return NS_OK;
}
const char *path = getenv("PATH");
if (!path)
const char* path = getenv("PATH");
if (!path) {
return NS_ERROR_FAILURE;
}
char *pathdup = strdup(path);
if (!pathdup)
char* pathdup = strdup(path);
if (!pathdup) {
return NS_ERROR_OUT_OF_MEMORY;
}
bool found = false;
char *token = strtok(pathdup, ":");
char* token = strtok(pathdup, ":");
while (token) {
char tmpPath[MAXPATHLEN];
sprintf(tmpPath, "%s/%s", token, argv0);
sprintf(tmpPath, "%s/%s", token, aArgv0);
if (realpath(tmpPath, aResult) && stat(aResult, &fileStat) == 0) {
found = true;
break;
@ -115,8 +127,9 @@ private:
token = strtok(nullptr, ":");
}
free(pathdup);
if (found)
if (found) {
return NS_OK;
}
return NS_ERROR_FAILURE;
}
@ -125,18 +138,19 @@ private:
#endif
public:
static nsresult GetFile(const char *argv0, nsIFile* *aResult)
static nsresult GetFile(const char* aArgv0, nsIFile** aResult)
{
nsCOMPtr<nsIFile> lf;
#ifdef XP_WIN
wchar_t exePath[MAXPATHLEN];
nsresult rv = GetW(argv0, exePath);
nsresult rv = GetW(aArgv0, exePath);
#else
char exePath[MAXPATHLEN];
nsresult rv = Get(argv0, exePath);
nsresult rv = Get(aArgv0, exePath);
#endif
if (NS_FAILED(rv))
if (NS_FAILED(rv)) {
return rv;
}
#ifdef XP_WIN
rv = NS_NewLocalFile(nsDependentString(exePath), true,
getter_AddRefs(lf));
@ -144,8 +158,9 @@ public:
rv = NS_NewNativeLocalFile(nsDependentCString(exePath), true,
getter_AddRefs(lf));
#endif
if (NS_FAILED(rv))
if (NS_FAILED(rv)) {
return rv;
}
NS_ADDREF(*aResult = lf);
return NS_OK;
}

View File

@ -16,95 +16,95 @@ FileLocation::~FileLocation()
{
}
FileLocation::FileLocation(nsIFile* file)
FileLocation::FileLocation(nsIFile* aFile)
{
Init(file);
Init(aFile);
}
FileLocation::FileLocation(nsIFile* file, const char *path)
FileLocation::FileLocation(nsIFile* aFile, const char* aPath)
{
Init(file, path);
Init(aFile, aPath);
}
FileLocation::FileLocation(const FileLocation &file, const char *path)
FileLocation::FileLocation(const FileLocation& aFile, const char* aPath)
{
if (file.IsZip()) {
if (file.mBaseFile) {
Init(file.mBaseFile, file.mPath.get());
if (aFile.IsZip()) {
if (aFile.mBaseFile) {
Init(aFile.mBaseFile, aFile.mPath.get());
} else {
Init(file.mBaseZip, file.mPath.get());
Init(aFile.mBaseZip, aFile.mPath.get());
}
if (path) {
if (aPath) {
int32_t i = mPath.RFindChar('/');
if (kNotFound == i) {
mPath.Truncate(0);
} else {
mPath.Truncate(i + 1);
}
mPath += path;
mPath += aPath;
}
} else {
if (path) {
if (aPath) {
nsCOMPtr<nsIFile> cfile;
file.mBaseFile->GetParent(getter_AddRefs(cfile));
aFile.mBaseFile->GetParent(getter_AddRefs(cfile));
#if defined(XP_WIN)
nsAutoCString pathStr(path);
char *p;
nsAutoCString pathStr(aPath);
char* p;
uint32_t len = pathStr.GetMutableData(&p);
for (; len; ++p, --len) {
if ('/' == *p) {
*p = '\\';
*p = '\\';
}
}
cfile->AppendRelativeNativePath(pathStr);
#else
cfile->AppendRelativeNativePath(nsDependentCString(path));
cfile->AppendRelativeNativePath(nsDependentCString(aPath));
#endif
Init(cfile);
} else {
Init(file.mBaseFile);
Init(aFile.mBaseFile);
}
}
}
void
FileLocation::Init(nsIFile* file)
FileLocation::Init(nsIFile* aFile)
{
mBaseZip = nullptr;
mBaseFile = file;
mBaseFile = aFile;
mPath.Truncate();
}
void
FileLocation::Init(nsIFile* file, const char* path)
FileLocation::Init(nsIFile* aFile, const char* aPath)
{
mBaseZip = nullptr;
mBaseFile = file;
mPath = path;
mBaseFile = aFile;
mPath = aPath;
}
void
FileLocation::Init(nsZipArchive* zip, const char* path)
FileLocation::Init(nsZipArchive* aZip, const char* aPath)
{
mBaseZip = zip;
mBaseZip = aZip;
mBaseFile = nullptr;
mPath = path;
mPath = aPath;
}
void
FileLocation::GetURIString(nsACString &result) const
FileLocation::GetURIString(nsACString& aResult) const
{
if (mBaseFile) {
net_GetURLSpecFromActualFile(mBaseFile, result);
net_GetURLSpecFromActualFile(mBaseFile, aResult);
} else if (mBaseZip) {
nsRefPtr<nsZipHandle> handler = mBaseZip->GetFD();
handler->mFile.GetURIString(result);
handler->mFile.GetURIString(aResult);
}
if (IsZip()) {
result.Insert("jar:", 0);
result += "!/";
result += mPath;
aResult.Insert("jar:", 0);
aResult += "!/";
aResult += mPath;
}
}
@ -113,8 +113,9 @@ FileLocation::GetBaseFile()
{
if (IsZip() && mBaseZip) {
nsRefPtr<nsZipHandle> handler = mBaseZip->GetFD();
if (handler)
if (handler) {
return handler->mFile.GetBaseFile();
}
return nullptr;
}
@ -123,17 +124,19 @@ FileLocation::GetBaseFile()
}
bool
FileLocation::Equals(const FileLocation &file) const
FileLocation::Equals(const FileLocation& aFile) const
{
if (mPath != file.mPath)
if (mPath != aFile.mPath) {
return false;
if (mBaseFile && file.mBaseFile) {
bool eq;
return NS_SUCCEEDED(mBaseFile->Equals(file.mBaseFile, &eq)) && eq;
}
const FileLocation *a = this, *b = &file;
if (mBaseFile && aFile.mBaseFile) {
bool eq;
return NS_SUCCEEDED(mBaseFile->Equals(aFile.mBaseFile, &eq)) && eq;
}
const FileLocation* a = this;
const FileLocation* b = &aFile;
if (a->mBaseZip) {
nsRefPtr<nsZipHandle> handler = a->mBaseZip->GetFD();
a = &handler->mFile;
@ -146,58 +149,64 @@ FileLocation::Equals(const FileLocation &file) const
}
nsresult
FileLocation::GetData(Data &data)
FileLocation::GetData(Data& aData)
{
if (!IsZip()) {
return mBaseFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &data.mFd.rwget());
return mBaseFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &aData.mFd.rwget());
}
data.mZip = mBaseZip;
if (!data.mZip) {
data.mZip = new nsZipArchive();
data.mZip->OpenArchive(mBaseFile);
aData.mZip = mBaseZip;
if (!aData.mZip) {
aData.mZip = new nsZipArchive();
aData.mZip->OpenArchive(mBaseFile);
}
data.mItem = data.mZip->GetItem(mPath.get());
if (data.mItem)
aData.mItem = aData.mZip->GetItem(mPath.get());
if (aData.mItem) {
return NS_OK;
}
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
}
nsresult
FileLocation::Data::GetSize(uint32_t *result)
FileLocation::Data::GetSize(uint32_t* aResult)
{
if (mFd) {
PRFileInfo64 fileInfo;
if (PR_SUCCESS != PR_GetOpenFileInfo64(mFd, &fileInfo))
if (PR_SUCCESS != PR_GetOpenFileInfo64(mFd, &fileInfo)) {
return NS_ErrorAccordingToNSPR();
}
if (fileInfo.size > int64_t(UINT32_MAX))
if (fileInfo.size > int64_t(UINT32_MAX)) {
return NS_ERROR_FILE_TOO_BIG;
}
*result = fileInfo.size;
*aResult = fileInfo.size;
return NS_OK;
} else if (mItem) {
*result = mItem->RealSize();
*aResult = mItem->RealSize();
return NS_OK;
}
return NS_ERROR_NOT_INITIALIZED;
}
nsresult
FileLocation::Data::Copy(char *buf, uint32_t len)
FileLocation::Data::Copy(char* aBuf, uint32_t aLen)
{
if (mFd) {
for (uint32_t totalRead = 0; totalRead < len; ) {
int32_t read = PR_Read(mFd, buf + totalRead, XPCOM_MIN(len - totalRead, uint32_t(INT32_MAX)));
if (read < 0)
for (uint32_t totalRead = 0; totalRead < aLen;) {
int32_t read = PR_Read(mFd, aBuf + totalRead,
XPCOM_MIN(aLen - totalRead, uint32_t(INT32_MAX)));
if (read < 0) {
return NS_ErrorAccordingToNSPR();
}
totalRead += read;
}
return NS_OK;
} else if (mItem) {
nsZipCursor cursor(mItem, mZip, reinterpret_cast<uint8_t *>(buf), len, true);
nsZipCursor cursor(mItem, mZip, reinterpret_cast<uint8_t*>(aBuf),
aLen, true);
uint32_t readLen;
cursor.Copy(&readLen);
return (readLen == len) ? NS_OK : NS_ERROR_FILE_CORRUPTED;
return (readLen == aLen) ? NS_OK : NS_ERROR_FILE_CORRUPTED;
}
return NS_ERROR_NOT_INITIALIZED;
}

View File

@ -36,34 +36,34 @@ public:
/**
* Constructor for plain files
*/
explicit FileLocation(nsIFile *file);
explicit FileLocation(nsIFile* aFile);
/**
* Constructors for path within an archive. The archive can be given either
* as nsIFile or nsZipArchive.
*/
FileLocation(nsIFile *zip, const char *path);
FileLocation(nsIFile* aZip, const char* aPath);
FileLocation(nsZipArchive *zip, const char *path);
FileLocation(nsZipArchive* aZip, const char* aPath);
/**
* Creates a new file location relative to another one.
*/
FileLocation(const FileLocation &file, const char *path = nullptr);
FileLocation(const FileLocation& aFile, const char* aPath = nullptr);
/**
* Initialization functions corresponding to constructors
*/
void Init(nsIFile *file);
void Init(nsIFile* aFile);
void Init(nsIFile *zip, const char *path);
void Init(nsIFile* aZip, const char* aPath);
void Init(nsZipArchive *zip, const char *path);
void Init(nsZipArchive* aZip, const char* aPath);
/**
* Returns an URI string corresponding to the file location
*/
void GetURIString(nsACString &result) const;
void GetURIString(nsACString& aResult) const;
/**
* Returns the base file of the location, where base file is defined as:
@ -76,32 +76,23 @@ public:
/**
* Returns whether the "base file" (see GetBaseFile) is an archive
*/
bool IsZip() const
{
return !mPath.IsEmpty();
}
bool IsZip() const { return !mPath.IsEmpty(); }
/**
* Returns the path within the archive, when within an archive
*/
void GetPath(nsACString &result) const
{
result = mPath;
}
void GetPath(nsACString& aResult) const { aResult = mPath; }
/**
* Boolean value corresponding to whether the file location is initialized
* or not.
*/
operator bool() const
{
return mBaseFile || mBaseZip;
}
operator bool() const { return mBaseFile || mBaseZip; }
/**
* Returns whether another FileLocation points to the same resource
*/
bool Equals(const FileLocation &file) const;
bool Equals(const FileLocation& aFile) const;
/**
* Data associated with a FileLocation.
@ -112,15 +103,15 @@ public:
/**
* Returns the data size
*/
nsresult GetSize(uint32_t *result);
nsresult GetSize(uint32_t* aResult);
/**
* Copies the data in the given buffer
*/
nsresult Copy(char *buf, uint32_t len);
nsresult Copy(char* aBuf, uint32_t aLen);
protected:
friend class FileLocation;
nsZipItem *mItem;
nsZipItem* mItem;
nsRefPtr<nsZipArchive> mZip;
mozilla::AutoFDClose mFd;
};
@ -129,7 +120,7 @@ public:
* Returns the data associated with the resource pointed at by the file
* location.
*/
nsresult GetData(Data &data);
nsresult GetData(Data& aData);
private:
nsCOMPtr<nsIFile> mBaseFile;
nsRefPtr<nsZipArchive> mBaseZip;

View File

@ -11,109 +11,112 @@
/**
* Private Method to register an exit routine. This method
* used to allow you to setup a callback that will be called from
* the NS_ShutdownXPCOM function after all services and
* used to allow you to setup a callback that will be called from
* the NS_ShutdownXPCOM function after all services and
* components have gone away. It was fatally flawed in that the component
* DLL could be released before the exit function was called; it is now a
* stub implementation that does nothing.
*/
XPCOM_API(nsresult)
NS_RegisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine, uint32_t priority);
NS_RegisterXPCOMExitRoutine(XPCOMExitRoutine aExitRoutine, uint32_t aPriority);
XPCOM_API(nsresult)
NS_UnregisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine);
NS_UnregisterXPCOMExitRoutine(XPCOMExitRoutine aExitRoutine);
static const XPCOMFunctions kFrozenFunctions = {
XPCOM_GLUE_VERSION,
sizeof(XPCOMFunctions),
&NS_InitXPCOM2,
&NS_ShutdownXPCOM,
&NS_GetServiceManager,
&NS_GetComponentManager,
&NS_GetComponentRegistrar,
&NS_GetMemoryManager,
&NS_NewLocalFile,
&NS_NewNativeLocalFile,
&NS_RegisterXPCOMExitRoutine,
&NS_UnregisterXPCOMExitRoutine,
XPCOM_GLUE_VERSION,
sizeof(XPCOMFunctions),
&NS_InitXPCOM2,
&NS_ShutdownXPCOM,
&NS_GetServiceManager,
&NS_GetComponentManager,
&NS_GetComponentRegistrar,
&NS_GetMemoryManager,
&NS_NewLocalFile,
&NS_NewNativeLocalFile,
&NS_RegisterXPCOMExitRoutine,
&NS_UnregisterXPCOMExitRoutine,
// these functions were added post 1.4
&NS_GetDebug,
nullptr,
// these functions were added post 1.4
&NS_GetDebug,
nullptr,
// these functions were added post 1.6
&NS_StringContainerInit,
&NS_StringContainerFinish,
&NS_StringGetData,
&NS_StringSetData,
&NS_StringSetDataRange,
&NS_StringCopy,
&NS_CStringContainerInit,
&NS_CStringContainerFinish,
&NS_CStringGetData,
&NS_CStringSetData,
&NS_CStringSetDataRange,
&NS_CStringCopy,
&NS_CStringToUTF16,
&NS_UTF16ToCString,
&NS_StringCloneData,
&NS_CStringCloneData,
// these functions were added post 1.6
&NS_StringContainerInit,
&NS_StringContainerFinish,
&NS_StringGetData,
&NS_StringSetData,
&NS_StringSetDataRange,
&NS_StringCopy,
&NS_CStringContainerInit,
&NS_CStringContainerFinish,
&NS_CStringGetData,
&NS_CStringSetData,
&NS_CStringSetDataRange,
&NS_CStringCopy,
&NS_CStringToUTF16,
&NS_UTF16ToCString,
&NS_StringCloneData,
&NS_CStringCloneData,
// these functions were added post 1.7 (post Firefox 1.0)
&NS_Alloc,
&NS_Realloc,
&NS_Free,
&NS_StringContainerInit2,
&NS_CStringContainerInit2,
&NS_StringGetMutableData,
&NS_CStringGetMutableData,
nullptr,
// these functions were added post 1.7 (post Firefox 1.0)
&NS_Alloc,
&NS_Realloc,
&NS_Free,
&NS_StringContainerInit2,
&NS_CStringContainerInit2,
&NS_StringGetMutableData,
&NS_CStringGetMutableData,
nullptr,
// these functions were added post 1.8
&NS_DebugBreak,
&NS_LogInit,
&NS_LogTerm,
&NS_LogAddRef,
&NS_LogRelease,
&NS_LogCtor,
&NS_LogDtor,
&NS_LogCOMPtrAddRef,
&NS_LogCOMPtrRelease,
&NS_GetXPTCallStub,
&NS_DestroyXPTCallStub,
&NS_InvokeByIndex,
nullptr,
nullptr,
&NS_StringSetIsVoid,
&NS_StringGetIsVoid,
&NS_CStringSetIsVoid,
&NS_CStringGetIsVoid,
// these functions were added post 1.8
&NS_DebugBreak,
&NS_LogInit,
&NS_LogTerm,
&NS_LogAddRef,
&NS_LogRelease,
&NS_LogCtor,
&NS_LogDtor,
&NS_LogCOMPtrAddRef,
&NS_LogCOMPtrRelease,
&NS_GetXPTCallStub,
&NS_DestroyXPTCallStub,
&NS_InvokeByIndex,
nullptr,
nullptr,
&NS_StringSetIsVoid,
&NS_StringGetIsVoid,
&NS_CStringSetIsVoid,
&NS_CStringGetIsVoid,
// these functions were added post 1.9, but then made obsolete
nullptr,
nullptr,
// these functions were added post 1.9, but then made obsolete
nullptr,
nullptr,
&NS_CycleCollectorSuspect3,
&NS_CycleCollectorSuspect3,
};
EXPORT_XPCOM_API(nsresult)
NS_GetFrozenFunctions(XPCOMFunctions *functions, const char* /* libraryPath */)
NS_GetFrozenFunctions(XPCOMFunctions* aFunctions, const char* /* aLibraryPath */)
{
if (!functions)
return NS_ERROR_OUT_OF_MEMORY;
if (!aFunctions) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (functions->version != XPCOM_GLUE_VERSION)
return NS_ERROR_FAILURE;
if (aFunctions->version != XPCOM_GLUE_VERSION) {
return NS_ERROR_FAILURE;
}
uint32_t size = functions->size;
if (size > sizeof(XPCOMFunctions))
size = sizeof(XPCOMFunctions);
uint32_t size = aFunctions->size;
if (size > sizeof(XPCOMFunctions)) {
size = sizeof(XPCOMFunctions);
}
size -= offsetof(XPCOMFunctions, init);
size -= offsetof(XPCOMFunctions, init);
memcpy(&functions->init, &kFrozenFunctions.init, size);
memcpy(&aFunctions->init, &kFrozenFunctions.init, size);
return NS_OK;
return NS_OK;
}
/*
@ -121,13 +124,13 @@ NS_GetFrozenFunctions(XPCOMFunctions *functions, const char* /* libraryPath */)
*/
EXPORT_XPCOM_API(nsresult)
NS_RegisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine, uint32_t priority)
NS_RegisterXPCOMExitRoutine(XPCOMExitRoutine aExitRoutine, uint32_t aPriority)
{
return NS_OK;
}
EXPORT_XPCOM_API(nsresult)
NS_UnregisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine)
NS_UnregisterXPCOMExitRoutine(XPCOMExitRoutine aExitRoutine)
{
return NS_OK;
}

View File

@ -26,18 +26,20 @@ namespace {
/** Find if a vector contains a specific element */
template<class T>
bool VectorContains(const std::vector<T>& vector, const T& element)
bool
VectorContains(const std::vector<T>& aVector, const T& aElement)
{
return std::find(vector.begin(), vector.end(), element) != vector.end();
return std::find(aVector.begin(), aVector.end(), aElement) != aVector.end();
}
/** Remove element from a vector */
template<class T>
void VectorRemove(std::vector<T>& vector, const T& element)
void
VectorRemove(std::vector<T>& aVector, const T& aElement)
{
typename std::vector<T>::iterator newEnd = std::remove(vector.begin(),
vector.end(), element);
vector.erase(newEnd, vector.end());
typename std::vector<T>::iterator newEnd =
std::remove(aVector.begin(), aVector.end(), aElement);
aVector.erase(newEnd, aVector.end());
}
/** Lists of Observers */
@ -49,11 +51,9 @@ private:
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ObserverLists)
ObserverLists()
{
}
ObserverLists() {}
ObserverLists(ObserverLists const & aOther)
ObserverLists(ObserverLists const& aOther)
: mCreateObservers(aOther.mCreateObservers)
, mReadObservers(aOther.mReadObservers)
, mWriteObservers(aOther.mWriteObservers)
@ -92,8 +92,7 @@ public:
MOZ_COUNT_DTOR(PerThreadData);
}
void
CallObservers(IOInterposeObserver::Observation& aObservation)
void CallObservers(IOInterposeObserver::Observation& aObservation)
{
// Prevent recursive reporting.
if (mIsHandlingObservation) {
@ -105,81 +104,55 @@ public:
std::vector<IOInterposeObserver*>* observers = nullptr;
switch (aObservation.ObservedOperation()) {
case IOInterposeObserver::OpCreateOrOpen:
{
observers = &mObserverLists->mCreateObservers;
}
observers = &mObserverLists->mCreateObservers;
break;
case IOInterposeObserver::OpRead:
{
observers = &mObserverLists->mReadObservers;
}
observers = &mObserverLists->mReadObservers;
break;
case IOInterposeObserver::OpWrite:
{
observers = &mObserverLists->mWriteObservers;
}
observers = &mObserverLists->mWriteObservers;
break;
case IOInterposeObserver::OpFSync:
{
observers = &mObserverLists->mFSyncObservers;
}
observers = &mObserverLists->mFSyncObservers;
break;
case IOInterposeObserver::OpStat:
{
observers = &mObserverLists->mStatObservers;
}
observers = &mObserverLists->mStatObservers;
break;
case IOInterposeObserver::OpClose:
{
observers = &mObserverLists->mCloseObservers;
}
observers = &mObserverLists->mCloseObservers;
break;
case IOInterposeObserver::OpNextStage:
{
observers = &mObserverLists->mStageObservers;
}
observers = &mObserverLists->mStageObservers;
break;
default:
{
// Invalid IO operation, see documentation comment for
// IOInterposer::Report()
MOZ_ASSERT(false);
// Just ignore it in non-debug builds.
return;
}
default: {
// Invalid IO operation, see documentation comment for
// IOInterposer::Report()
MOZ_ASSERT(false);
// Just ignore it in non-debug builds.
return;
}
}
MOZ_ASSERT(observers);
// Inform observers
for (std::vector<IOInterposeObserver*>::iterator i = observers->begin(),
e = observers->end(); i != e; ++i)
{
for (auto i = observers->begin(), e = observers->end(); i != e; ++i) {
(*i)->Observe(aObservation);
}
mIsHandlingObservation = false;
}
inline uint32_t
GetCurrentGeneration() const
{
return mCurrentGeneration;
}
inline uint32_t GetCurrentGeneration() const { return mCurrentGeneration; }
inline bool
IsMainThread() const
{
return mIsMainThread;
}
inline bool IsMainThread() const { return mIsMainThread; }
inline void
SetObserverLists(uint32_t aNewGeneration, RefPtr<ObserverLists>& aNewLists)
inline void SetObserverLists(uint32_t aNewGeneration,
RefPtr<ObserverLists>& aNewLists)
{
mCurrentGeneration = aNewGeneration;
mObserverLists = aNewLists;
}
inline void
ClearObserverLists()
inline void ClearObserverLists()
{
if (mObserverLists) {
mCurrentGeneration = 0;
@ -209,14 +182,10 @@ public:
MOZ_COUNT_DTOR(MasterList);
}
inline void
Disable()
{
mIsEnabled = false;
}
inline void Disable() { mIsEnabled = false; }
void
Register(IOInterposeObserver::Operation aOp, IOInterposeObserver* aObserver)
void Register(IOInterposeObserver::Operation aOp,
IOInterposeObserver* aObserver)
{
IOInterposer::AutoLock lock(mLock);
@ -257,14 +226,14 @@ public:
newLists->mStageObservers.push_back(aObserver);
}
mObserverLists = newLists;
mObservedOperations = (IOInterposeObserver::Operation)
(mObservedOperations | aOp);
mObservedOperations =
(IOInterposeObserver::Operation)(mObservedOperations | aOp);
mCurrentGeneration++;
}
void
Unregister(IOInterposeObserver::Operation aOp, IOInterposeObserver* aObserver)
void Unregister(IOInterposeObserver::Operation aOp,
IOInterposeObserver* aObserver)
{
IOInterposer::AutoLock lock(mLock);
@ -278,59 +247,64 @@ public:
if (aOp & IOInterposeObserver::OpCreateOrOpen) {
VectorRemove(newLists->mCreateObservers, aObserver);
if (newLists->mCreateObservers.empty()) {
mObservedOperations = (IOInterposeObserver::Operation)
(mObservedOperations &
~IOInterposeObserver::OpCreateOrOpen);
mObservedOperations =
(IOInterposeObserver::Operation)(mObservedOperations &
~IOInterposeObserver::OpCreateOrOpen);
}
}
if (aOp & IOInterposeObserver::OpRead) {
VectorRemove(newLists->mReadObservers, aObserver);
if (newLists->mReadObservers.empty()) {
mObservedOperations = (IOInterposeObserver::Operation)
(mObservedOperations & ~IOInterposeObserver::OpRead);
mObservedOperations =
(IOInterposeObserver::Operation)(mObservedOperations &
~IOInterposeObserver::OpRead);
}
}
if (aOp & IOInterposeObserver::OpWrite) {
VectorRemove(newLists->mWriteObservers, aObserver);
if (newLists->mWriteObservers.empty()) {
mObservedOperations = (IOInterposeObserver::Operation)
(mObservedOperations & ~IOInterposeObserver::OpWrite);
mObservedOperations =
(IOInterposeObserver::Operation)(mObservedOperations &
~IOInterposeObserver::OpWrite);
}
}
if (aOp & IOInterposeObserver::OpFSync) {
VectorRemove(newLists->mFSyncObservers, aObserver);
if (newLists->mFSyncObservers.empty()) {
mObservedOperations = (IOInterposeObserver::Operation)
(mObservedOperations & ~IOInterposeObserver::OpFSync);
mObservedOperations =
(IOInterposeObserver::Operation)(mObservedOperations &
~IOInterposeObserver::OpFSync);
}
}
if (aOp & IOInterposeObserver::OpStat) {
VectorRemove(newLists->mStatObservers, aObserver);
if (newLists->mStatObservers.empty()) {
mObservedOperations = (IOInterposeObserver::Operation)
(mObservedOperations & ~IOInterposeObserver::OpStat);
mObservedOperations =
(IOInterposeObserver::Operation)(mObservedOperations &
~IOInterposeObserver::OpStat);
}
}
if (aOp & IOInterposeObserver::OpClose) {
VectorRemove(newLists->mCloseObservers, aObserver);
if (newLists->mCloseObservers.empty()) {
mObservedOperations = (IOInterposeObserver::Operation)
(mObservedOperations & ~IOInterposeObserver::OpClose);
mObservedOperations =
(IOInterposeObserver::Operation)(mObservedOperations &
~IOInterposeObserver::OpClose);
}
}
if (aOp & IOInterposeObserver::OpNextStage) {
VectorRemove(newLists->mStageObservers, aObserver);
if (newLists->mStageObservers.empty()) {
mObservedOperations = (IOInterposeObserver::Operation)
(mObservedOperations & ~IOInterposeObserver::OpNextStage);
mObservedOperations =
(IOInterposeObserver::Operation)(mObservedOperations &
~IOInterposeObserver::OpNextStage);
}
}
mObserverLists = newLists;
mCurrentGeneration++;
}
void
Update(PerThreadData &aPtd)
void Update(PerThreadData& aPtd)
{
if (mCurrentGeneration == aPtd.GetCurrentGeneration()) {
return;
@ -341,8 +315,7 @@ public:
aPtd.SetObserverLists(mCurrentGeneration, mObserverLists);
}
inline bool
IsObservedOperation(IOInterposeObserver::Operation aOp)
inline bool IsObservedOperation(IOInterposeObserver::Operation aOp)
{
// The quick reader may observe that no locks are being employed here,
// hence the result of the operations is truly undefined. However, most
@ -413,7 +386,7 @@ IOInterposeObserver::Observation::Observation(Operation aOperation,
const char*
IOInterposeObserver::Observation::ObservedOperationString() const
{
switch(mOperation) {
switch (mOperation) {
case OpCreateOrOpen:
return "create/open";
case OpRead:
@ -453,8 +426,8 @@ IOInterposer::Init()
return false;
}
#if defined(XP_WIN)
bool isMainThread = XRE_GetWindowsEnvironment() !=
WindowsEnvironmentType_Metro;
bool isMainThread =
XRE_GetWindowsEnvironment() != WindowsEnvironmentType_Metro;
#else
bool isMainThread = true;
#endif
@ -479,7 +452,7 @@ IOInterposeObserver::IsMainThread()
if (!sThreadLocalData.initialized()) {
return false;
}
PerThreadData *ptd = sThreadLocalData.get();
PerThreadData* ptd = sThreadLocalData.get();
if (!ptd) {
return false;
}

View File

@ -61,10 +61,7 @@ public:
* Operation observed, this is one of the individual Operation values.
* Combinations of these flags are only used when registering observers.
*/
Operation ObservedOperation() const
{
return mOperation;
}
Operation ObservedOperation() const { return mOperation; }
/**
* Return the observed operation as a human-readable string.
@ -72,28 +69,19 @@ public:
const char* ObservedOperationString() const;
/** Time at which the I/O operation was started */
TimeStamp Start() const
{
return mStart;
}
TimeStamp Start() const { return mStart; }
/**
* Time at which the I/O operation ended, for asynchronous methods this is
* the time at which the call initiating the asynchronous request returned.
*/
TimeStamp End() const
{
return mEnd;
}
TimeStamp End() const { return mEnd; }
/**
* Duration of the operation, for asynchronous I/O methods this is the
* duration of the call initiating the asynchronous request.
*/
TimeDuration Duration() const
{
return mEnd - mStart;
}
TimeDuration Duration() const { return mEnd - mStart; }
/**
* IO reference, function name or name of component (sqlite) that did IO
@ -102,20 +90,12 @@ public:
* E.g. sqlite-commit, CreateFile, NtReadFile, fread, fsync, mmap, etc.
* I.e. typically the platform specific function that did the IO.
*/
const char* Reference() const
{
return mReference;
}
const char* Reference() const { return mReference; }
/** Request filename associated with the I/O operation, null if unknown */
virtual const char16_t* Filename()
{
return nullptr;
}
virtual const char16_t* Filename() { return nullptr; }
virtual ~Observation()
{
}
virtual ~Observation() {}
protected:
void
@ -140,9 +120,7 @@ public:
*/
virtual void Observe(Observation& aObservation) = 0;
virtual ~IOInterposeObserver()
{
}
virtual ~IOInterposeObserver() {}
protected:
/**
@ -157,118 +135,116 @@ protected:
* These functions are responsible for ensuring that events are routed to the
* appropriate observers.
*/
namespace IOInterposer
{
/**
* This function must be called from the main-thread when no other threads are
* running before any of the other methods on this class may be used.
*
* IO reports can however, safely assume that IsObservedOperation() will
* return false until the IOInterposer is initialized.
*
* Remark, it's safe to call this method multiple times, so just call it when
* you to utilize IO interposing.
*
* Using the IOInterposerInit class is preferred to calling this directly.
*/
bool Init();
namespace IOInterposer {
/**
* This function must be called from the main thread, and furthermore
* it must be called when no other threads are executing. Effectively
* restricting us to calling it only during shutdown.
*
* Callers should take care that no other consumers are subscribed to events,
* as these events will stop when this function is called.
*
* In practice, we don't use this method as the IOInterposer is used for
* late-write checks.
*/
void Clear();
/**
* This function must be called from the main-thread when no other threads are
* running before any of the other methods on this class may be used.
*
* IO reports can however, safely assume that IsObservedOperation() will
* return false until the IOInterposer is initialized.
*
* Remark, it's safe to call this method multiple times, so just call it when
* you to utilize IO interposing.
*
* Using the IOInterposerInit class is preferred to calling this directly.
*/
bool Init();
/**
* This function immediately disables IOInterposer functionality in a fast,
* thread-safe manner. Primarily for use by the crash reporter.
*/
void Disable();
/**
* This function must be called from the main thread, and furthermore
* it must be called when no other threads are executing. Effectively
* restricting us to calling it only during shutdown.
*
* Callers should take care that no other consumers are subscribed to events,
* as these events will stop when this function is called.
*
* In practice, we don't use this method as the IOInterposer is used for
* late-write checks.
*/
void Clear();
/**
* Report IO to registered observers.
* Notice that the reported operation must be either OpRead, OpWrite or
* OpFSync. You are not allowed to report an observation with OpWriteFSync or
* OpAll, these are just auxiliary values for use with Register().
*
* If the IO call you're reporting does multiple things, write and fsync, you
* can choose to call Report() twice once with write and once with FSync. You
* may not call Report() with OpWriteFSync! The Observation::mOperation
* attribute is meant to be generic, not perfect.
*
* Notice that there is no reason to report an observation with an operation
* which is not being observed. Use IsObservedOperation() to check if the
* operation you are about to report is being observed. This is especially
* important if you are constructing expensive observations containing
* filename and full-path.
*
* Remark: Init() must be called before any IO is reported. But
* IsObservedOperation() will return false until Init() is called.
*/
void Report(IOInterposeObserver::Observation& aObservation);
/**
* This function immediately disables IOInterposer functionality in a fast,
* thread-safe manner. Primarily for use by the crash reporter.
*/
void Disable();
/**
* Return whether or not an operation is observed. Reporters should not
* report operations that are not being observed by anybody. This mechanism
* allows us to avoid reporting I/O when no observers are registered.
*/
bool IsObservedOperation(IOInterposeObserver::Operation aOp);
/**
* Report IO to registered observers.
* Notice that the reported operation must be either OpRead, OpWrite or
* OpFSync. You are not allowed to report an observation with OpWriteFSync or
* OpAll, these are just auxiliary values for use with Register().
*
* If the IO call you're reporting does multiple things, write and fsync, you
* can choose to call Report() twice once with write and once with FSync. You
* may not call Report() with OpWriteFSync! The Observation::mOperation
* attribute is meant to be generic, not perfect.
*
* Notice that there is no reason to report an observation with an operation
* which is not being observed. Use IsObservedOperation() to check if the
* operation you are about to report is being observed. This is especially
* important if you are constructing expensive observations containing
* filename and full-path.
*
* Remark: Init() must be called before any IO is reported. But
* IsObservedOperation() will return false until Init() is called.
*/
void Report(IOInterposeObserver::Observation& aObservation);
/**
* Register IOInterposeObserver, the observer object will receive all
* observations for the given operation aOp.
*
* Remark: Init() must be called before observers are registered.
*/
void Register(IOInterposeObserver::Operation aOp,
/**
* Return whether or not an operation is observed. Reporters should not
* report operations that are not being observed by anybody. This mechanism
* allows us to avoid reporting I/O when no observers are registered.
*/
bool IsObservedOperation(IOInterposeObserver::Operation aOp);
/**
* Register IOInterposeObserver, the observer object will receive all
* observations for the given operation aOp.
*
* Remark: Init() must be called before observers are registered.
*/
void Register(IOInterposeObserver::Operation aOp,
IOInterposeObserver* aObserver);
/**
* Unregister an IOInterposeObserver for a given operation
* Remark: It is always safe to unregister for all operations, even if yoú
* didn't register for them all.
* I.e. IOInterposer::Unregister(IOInterposeObserver::OpAll, aObserver)
*
* Remark: Init() must be called before observers are unregistered.
*/
void Unregister(IOInterposeObserver::Operation aOp,
IOInterposeObserver* aObserver);
/**
* Unregister an IOInterposeObserver for a given operation
* Remark: It is always safe to unregister for all operations, even if yoú
* didn't register for them all.
* I.e. IOInterposer::Unregister(IOInterposeObserver::OpAll, aObserver)
*
* Remark: Init() must be called before observers are unregistered.
*/
void Unregister(IOInterposeObserver::Operation aOp,
IOInterposeObserver* aObserver);
/**
* Registers the current thread with the IOInterposer. This must be done to
* ensure that per-thread data is created in an orderly fashion.
* We could have written this to initialize that data lazily, however this
* could have unintended consequences if a thread that is not aware of
* IOInterposer was implicitly registered: its per-thread data would never
* be deleted because it would not know to unregister itself.
*
* @param aIsMainThread true if IOInterposer should treat the current thread
* as the main thread.
*/
void RegisterCurrentThread(bool aIsMainThread = false);
/**
* Registers the current thread with the IOInterposer. This must be done to
* ensure that per-thread data is created in an orderly fashion.
* We could have written this to initialize that data lazily, however this
* could have unintended consequences if a thread that is not aware of
* IOInterposer was implicitly registered: its per-thread data would never
* be deleted because it would not know to unregister itself.
*
* @param aIsMainThread true if IOInterposer should treat the current thread
* as the main thread.
*/
void
RegisterCurrentThread(bool aIsMainThread = false);
/**
* Unregisters the current thread with the IOInterposer. This is important
* to call when a thread is shutting down because it cleans up data that
* is stored in a TLS slot.
*/
void UnregisterCurrentThread();
/**
* Unregisters the current thread with the IOInterposer. This is important
* to call when a thread is shutting down because it cleans up data that
* is stored in a TLS slot.
*/
void
UnregisterCurrentThread();
/**
* Called to inform observers that the process has transitioned out of the
* startup stage or into the shutdown stage. Main thread only.
*/
void EnteringNextStage();
/**
* Called to inform observers that the process has transitioned out of the
* startup stage or into the shutdown stage. Main thread only.
*/
void
EnteringNextStage();
} // namespace IOInterposer
class IOInterposerInit

View File

@ -71,7 +71,7 @@ private:
class MonitorAutoLock
{
public:
explicit MonitorAutoLock(Monitor &aMonitor)
explicit MonitorAutoLock(Monitor& aMonitor)
: mMonitor(aMonitor)
{
mMonitor.Lock();
@ -99,7 +99,7 @@ private:
class MonitorAutoUnlock
{
public:
explicit MonitorAutoUnlock(Monitor &aMonitor)
explicit MonitorAutoUnlock(Monitor& aMonitor)
: mMonitor(aMonitor)
{
mMonitor.Unlock();

View File

@ -47,42 +47,43 @@ using namespace mozilla;
class SHA1Stream
{
public:
explicit SHA1Stream(FILE *stream)
: mFile(stream)
{
MozillaRegisterDebugFILE(mFile);
}
explicit SHA1Stream(FILE* aStream)
: mFile(aStream)
{
MozillaRegisterDebugFILE(mFile);
}
void Printf(const char *aFormat, ...)
{
MOZ_ASSERT(mFile);
va_list list;
va_start(list, aFormat);
nsAutoCString str;
str.AppendPrintf(aFormat, list);
va_end(list);
mSHA1.update(str.get(), str.Length());
fwrite(str.get(), 1, str.Length(), mFile);
}
void Finish(SHA1Sum::Hash &aHash)
{
int fd = fileno(mFile);
fflush(mFile);
MozillaUnRegisterDebugFD(fd);
fclose(mFile);
mSHA1.finish(aHash);
mFile = nullptr;
}
void Printf(const char* aFormat, ...)
{
MOZ_ASSERT(mFile);
va_list list;
va_start(list, aFormat);
nsAutoCString str;
str.AppendPrintf(aFormat, list);
va_end(list);
mSHA1.update(str.get(), str.Length());
fwrite(str.get(), 1, str.Length(), mFile);
}
void Finish(SHA1Sum::Hash& aHash)
{
int fd = fileno(mFile);
fflush(mFile);
MozillaUnRegisterDebugFD(fd);
fclose(mFile);
mSHA1.finish(aHash);
mFile = nullptr;
}
private:
FILE *mFile;
SHA1Sum mSHA1;
FILE* mFile;
SHA1Sum mSHA1;
};
static void RecordStackWalker(void *aPC, void *aSP, void *aClosure)
static void
RecordStackWalker(void* aPC, void* aSP, void* aClosure)
{
std::vector<uintptr_t> *stack =
static_cast<std::vector<uintptr_t>*>(aClosure);
stack->push_back(reinterpret_cast<uintptr_t>(aPC));
std::vector<uintptr_t>* stack =
static_cast<std::vector<uintptr_t>*>(aClosure);
stack->push_back(reinterpret_cast<uintptr_t>(aPC));
}
/**************************** Late-Write Observer ****************************/
@ -98,7 +99,8 @@ public:
: mProfileDirectory(PL_strdup(aProfileDirectory))
{
}
~LateWriteObserver() {
~LateWriteObserver()
{
PL_strfree(mProfileDirectory);
mProfileDirectory = nullptr;
}
@ -108,7 +110,8 @@ private:
char* mProfileDirectory;
};
void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb)
void
LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb)
{
#ifdef OBSERVE_LATE_WRITES
// Crash if that is the shutdown check mode
@ -131,12 +134,12 @@ void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb)
nsPrintfCString nameAux("%s%s%s", mProfileDirectory,
NS_SLASH, "Telemetry.LateWriteTmpXXXXXX");
char *name;
char* name;
nameAux.GetMutableData(&name);
// We want the sha1 of the entire file, so please don't write to fd
// directly; use sha1Stream.
FILE *stream;
FILE* stream;
#ifdef XP_WIN
HANDLE hFile;
do {
@ -175,8 +178,7 @@ void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb)
size_t numFrames = stack.GetStackSize();
sha1Stream.Printf("%u\n", (unsigned)numFrames);
for (size_t i = 0; i < numFrames; ++i) {
const Telemetry::ProcessedStack::Frame &frame =
stack.GetFrame(i);
const Telemetry::ProcessedStack::Frame& frame = stack.GetFrame(i);
// NOTE: We write the offsets, while the atos tool expects a value with
// the virtual address added. For example, running otool -l on the the firefox
// binary shows
@ -213,9 +215,10 @@ void LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb)
static StaticAutoPtr<LateWriteObserver> sLateWriteObserver;
namespace mozilla{
namespace mozilla {
void InitLateWriteChecks()
void
InitLateWriteChecks()
{
nsCOMPtr<nsIFile> mozFile;
NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mozFile));
@ -228,7 +231,8 @@ void InitLateWriteChecks()
}
}
void BeginLateWriteChecks()
void
BeginLateWriteChecks()
{
if (sLateWriteObserver) {
IOInterposer::Register(
@ -238,7 +242,8 @@ void BeginLateWriteChecks()
}
}
void StopLateWriteChecks()
void
StopLateWriteChecks()
{
if (sLateWriteObserver) {
IOInterposer::Unregister(

View File

@ -15,7 +15,8 @@
namespace mozilla {
/** Different shutdown check modes */
enum ShutdownChecksMode {
enum ShutdownChecksMode
{
SCM_CRASH, /** Crash on shutdown check failure */
SCM_RECORD, /** Record shutdown check violations */
SCM_NOTHING /** Don't attempt any shutdown checks */
@ -54,6 +55,6 @@ void BeginLateWriteChecks();
*/
void StopLateWriteChecks();
} // mozilla
} // namespace mozilla
#endif // mozilla_LateWriteChecks_h

View File

@ -28,7 +28,7 @@ namespace {
struct ObservationWithStack
{
ObservationWithStack(mozilla::IOInterposeObserver::Observation& aObs,
ProfilerBacktrace *aStack)
ProfilerBacktrace* aStack)
: mObservation(aObs)
, mStack(aStack)
{
@ -37,7 +37,7 @@ struct ObservationWithStack
mFilename = filename;
}
}
mozilla::IOInterposeObserver::Observation mObservation;
ProfilerBacktrace* mStack;
nsString mFilename;
@ -83,7 +83,8 @@ MainThreadIOLoggerImpl::~MainThreadIOLoggerImpl()
if (!mIOThread) {
return;
}
{ // Scope for lock
{
// Scope for lock
IOInterposer::MonitorAutoLock lock(mMonitor);
mShutdownRequired = true;
lock.Notify();
@ -133,7 +134,8 @@ MainThreadIOLoggerImpl::IOThreadFunc()
return;
}
mLogStartTime = TimeStamp::Now();
{ // Scope for lock
{
// Scope for lock
IOInterposer::MonitorAutoLock lock(mMonitor);
while (true) {
while (!mShutdownRequired && mObservations.empty()) {
@ -145,13 +147,12 @@ MainThreadIOLoggerImpl::IOThreadFunc()
// Pull events off the shared array onto a local one
std::vector<ObservationWithStack> observationsToWrite;
observationsToWrite.swap(mObservations);
// Release the lock so that we're not holding anybody up during I/O
IOInterposer::MonitorAutoUnlock unlock(mMonitor);
// Now write the events.
for (std::vector<ObservationWithStack>::iterator
i = observationsToWrite.begin(), e = observationsToWrite.end();
for (auto i = observationsToWrite.begin(), e = observationsToWrite.end();
i != e; ++i) {
if (i->mObservation.ObservedOperation() == OpNextStage) {
PR_fprintf(fd, "%f,NEXT-STAGE\n",

View File

@ -38,7 +38,8 @@ public:
}
};
PRStatus PR_CALLBACK interposedClose(PRFileDesc* aFd)
PRStatus PR_CALLBACK
interposedClose(PRFileDesc* aFd)
{
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sCloseFn, "NSPR IO Interposing: sCloseFn is NULL");
@ -47,7 +48,8 @@ PRStatus PR_CALLBACK interposedClose(PRFileDesc* aFd)
return sCloseFn(aFd);
}
int32_t PR_CALLBACK interposedRead(PRFileDesc* aFd, void* aBuf, int32_t aAmt)
int32_t PR_CALLBACK
interposedRead(PRFileDesc* aFd, void* aBuf, int32_t aAmt)
{
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sReadFn, "NSPR IO Interposing: sReadFn is NULL");
@ -56,8 +58,8 @@ int32_t PR_CALLBACK interposedRead(PRFileDesc* aFd, void* aBuf, int32_t aAmt)
return sReadFn(aFd, aBuf, aAmt);
}
int32_t PR_CALLBACK interposedWrite(PRFileDesc* aFd, const void* aBuf,
int32_t aAmt)
int32_t PR_CALLBACK
interposedWrite(PRFileDesc* aFd, const void* aBuf, int32_t aAmt)
{
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sWriteFn, "NSPR IO Interposing: sWriteFn is NULL");
@ -66,7 +68,8 @@ int32_t PR_CALLBACK interposedWrite(PRFileDesc* aFd, const void* aBuf,
return sWriteFn(aFd, aBuf, aAmt);
}
PRStatus PR_CALLBACK interposedFSync(PRFileDesc* aFd)
PRStatus PR_CALLBACK
interposedFSync(PRFileDesc* aFd)
{
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sFSyncFn, "NSPR IO Interposing: sFSyncFn is NULL");
@ -75,7 +78,8 @@ PRStatus PR_CALLBACK interposedFSync(PRFileDesc* aFd)
return sFSyncFn(aFd);
}
PRStatus PR_CALLBACK interposedFileInfo(PRFileDesc *aFd, PRFileInfo *aInfo)
PRStatus PR_CALLBACK
interposedFileInfo(PRFileDesc* aFd, PRFileInfo* aInfo)
{
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sFileInfoFn, "NSPR IO Interposing: sFileInfoFn is NULL");
@ -84,7 +88,8 @@ PRStatus PR_CALLBACK interposedFileInfo(PRFileDesc *aFd, PRFileInfo *aInfo)
return sFileInfoFn(aFd, aInfo);
}
PRStatus PR_CALLBACK interposedFileInfo64(PRFileDesc *aFd, PRFileInfo64 *aInfo)
PRStatus PR_CALLBACK
interposedFileInfo64(PRFileDesc* aFd, PRFileInfo64* aInfo)
{
// If we don't have a valid original function pointer something is very wrong.
NS_ASSERTION(sFileInfo64Fn, "NSPR IO Interposing: sFileInfo64Fn is NULL");
@ -97,7 +102,8 @@ PRStatus PR_CALLBACK interposedFileInfo64(PRFileDesc *aFd, PRFileInfo64 *aInfo)
namespace mozilla {
void InitNSPRIOInterposing()
void
InitNSPRIOInterposing()
{
// Check that we have not interposed any of the IO methods before
MOZ_ASSERT(!sCloseFn && !sReadFn && !sWriteFn && !sFSyncFn && !sFileInfoFn &&
@ -135,7 +141,8 @@ void InitNSPRIOInterposing()
methods->fileInfo64 = &interposedFileInfo64;
}
void ClearNSPRIOInterposing()
void
ClearNSPRIOInterposing()
{
// If we have already cleared IO interposing, or not initialized it this is
// actually bad.

View File

@ -13,157 +13,172 @@
namespace mozilla {
nsIFile *Omnijar::sPath[2] = { nullptr, nullptr };
nsZipArchive *Omnijar::sReader[2] = { nullptr, nullptr };
nsIFile* Omnijar::sPath[2] = { nullptr, nullptr };
nsZipArchive* Omnijar::sReader[2] = { nullptr, nullptr };
bool Omnijar::sInitialized = false;
static bool sIsUnified = false;
static bool sIsNested[2] = { false, false };
static const char *sProp[2] =
{ NS_GRE_DIR, NS_XPCOM_CURRENT_PROCESS_DIR };
static const char* sProp[2] = {
NS_GRE_DIR, NS_XPCOM_CURRENT_PROCESS_DIR
};
#define SPROP(Type) ((Type == mozilla::Omnijar::GRE) ? sProp[GRE] : sProp[APP])
void
Omnijar::CleanUpOne(Type aType)
{
if (sReader[aType]) {
sReader[aType]->CloseArchive();
NS_IF_RELEASE(sReader[aType]);
}
sReader[aType] = nullptr;
NS_IF_RELEASE(sPath[aType]);
if (sReader[aType]) {
sReader[aType]->CloseArchive();
NS_IF_RELEASE(sReader[aType]);
}
sReader[aType] = nullptr;
NS_IF_RELEASE(sPath[aType]);
}
void
Omnijar::InitOne(nsIFile *aPath, Type aType)
Omnijar::InitOne(nsIFile* aPath, Type aType)
{
nsCOMPtr<nsIFile> file;
if (aPath) {
file = aPath;
} else {
nsCOMPtr<nsIFile> dir;
nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile), getter_AddRefs(dir));
NS_NAMED_LITERAL_CSTRING (kOmnijarName, NS_STRINGIFY(OMNIJAR_NAME));
if (NS_FAILED(dir->Clone(getter_AddRefs(file))) ||
NS_FAILED(file->AppendNative(kOmnijarName)))
return;
nsCOMPtr<nsIFile> file;
if (aPath) {
file = aPath;
} else {
nsCOMPtr<nsIFile> dir;
nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile),
getter_AddRefs(dir));
NS_NAMED_LITERAL_CSTRING(kOmnijarName, NS_STRINGIFY(OMNIJAR_NAME));
if (NS_FAILED(dir->Clone(getter_AddRefs(file))) ||
NS_FAILED(file->AppendNative(kOmnijarName))) {
return;
}
bool isFile;
if (NS_FAILED(file->IsFile(&isFile)) || !isFile) {
// If we're not using an omni.jar for GRE, and we don't have an
// omni.jar for APP, check if both directories are the same.
if ((aType == APP) && (!sPath[GRE])) {
nsCOMPtr<nsIFile> greDir, appDir;
bool equals;
nsDirectoryService::gService->Get(SPROP(GRE), NS_GET_IID(nsIFile), getter_AddRefs(greDir));
nsDirectoryService::gService->Get(SPROP(APP), NS_GET_IID(nsIFile), getter_AddRefs(appDir));
if (NS_SUCCEEDED(greDir->Equals(appDir, &equals)) && equals)
sIsUnified = true;
}
return;
}
bool equals;
if ((aType == APP) && (sPath[GRE]) &&
NS_SUCCEEDED(sPath[GRE]->Equals(file, &equals)) && equals) {
// If we're using omni.jar on both GRE and APP and their path
// is the same, we're in the unified case.
}
bool isFile;
if (NS_FAILED(file->IsFile(&isFile)) || !isFile) {
// If we're not using an omni.jar for GRE, and we don't have an
// omni.jar for APP, check if both directories are the same.
if ((aType == APP) && (!sPath[GRE])) {
nsCOMPtr<nsIFile> greDir, appDir;
bool equals;
nsDirectoryService::gService->Get(SPROP(GRE), NS_GET_IID(nsIFile),
getter_AddRefs(greDir));
nsDirectoryService::gService->Get(SPROP(APP), NS_GET_IID(nsIFile),
getter_AddRefs(appDir));
if (NS_SUCCEEDED(greDir->Equals(appDir, &equals)) && equals) {
sIsUnified = true;
return;
}
}
return;
}
nsRefPtr<nsZipArchive> zipReader = new nsZipArchive();
if (NS_FAILED(zipReader->OpenArchive(file))) {
return;
bool equals;
if ((aType == APP) && (sPath[GRE]) &&
NS_SUCCEEDED(sPath[GRE]->Equals(file, &equals)) && equals) {
// If we're using omni.jar on both GRE and APP and their path
// is the same, we're in the unified case.
sIsUnified = true;
return;
}
nsRefPtr<nsZipArchive> zipReader = new nsZipArchive();
if (NS_FAILED(zipReader->OpenArchive(file))) {
return;
}
nsRefPtr<nsZipHandle> handle;
if (NS_SUCCEEDED(nsZipHandle::Init(zipReader, NS_STRINGIFY(OMNIJAR_NAME),
getter_AddRefs(handle)))) {
zipReader = new nsZipArchive();
if (NS_FAILED(zipReader->OpenArchive(handle))) {
return;
}
sIsNested[aType] = true;
}
nsRefPtr<nsZipHandle> handle;
if (NS_SUCCEEDED(nsZipHandle::Init(zipReader, NS_STRINGIFY(OMNIJAR_NAME), getter_AddRefs(handle)))) {
zipReader = new nsZipArchive();
if (NS_FAILED(zipReader->OpenArchive(handle)))
return;
sIsNested[aType] = true;
}
CleanUpOne(aType);
sReader[aType] = zipReader;
NS_IF_ADDREF(sReader[aType]);
sPath[aType] = file;
NS_IF_ADDREF(sPath[aType]);
CleanUpOne(aType);
sReader[aType] = zipReader;
NS_IF_ADDREF(sReader[aType]);
sPath[aType] = file;
NS_IF_ADDREF(sPath[aType]);
}
void
Omnijar::Init(nsIFile *aGrePath, nsIFile *aAppPath)
Omnijar::Init(nsIFile* aGrePath, nsIFile* aAppPath)
{
InitOne(aGrePath, GRE);
InitOne(aAppPath, APP);
sInitialized = true;
InitOne(aGrePath, GRE);
InitOne(aAppPath, APP);
sInitialized = true;
}
void
Omnijar::CleanUp()
{
CleanUpOne(GRE);
CleanUpOne(APP);
sInitialized = false;
CleanUpOne(GRE);
CleanUpOne(APP);
sInitialized = false;
}
already_AddRefed<nsZipArchive>
Omnijar::GetReader(nsIFile *aPath)
Omnijar::GetReader(nsIFile* aPath)
{
NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
bool equals;
nsresult rv;
bool equals;
nsresult rv;
if (sPath[GRE] && !sIsNested[GRE]) {
rv = sPath[GRE]->Equals(aPath, &equals);
if (NS_SUCCEEDED(rv) && equals)
return GetReader(GRE);
if (sPath[GRE] && !sIsNested[GRE]) {
rv = sPath[GRE]->Equals(aPath, &equals);
if (NS_SUCCEEDED(rv) && equals) {
return GetReader(GRE);
}
if (sPath[APP] && !sIsNested[APP]) {
rv = sPath[APP]->Equals(aPath, &equals);
if (NS_SUCCEEDED(rv) && equals)
return GetReader(APP);
}
if (sPath[APP] && !sIsNested[APP]) {
rv = sPath[APP]->Equals(aPath, &equals);
if (NS_SUCCEEDED(rv) && equals) {
return GetReader(APP);
}
return nullptr;
}
return nullptr;
}
nsresult
Omnijar::GetURIString(Type aType, nsACString &result)
Omnijar::GetURIString(Type aType, nsACString& aResult)
{
NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
result.Truncate();
aResult.Truncate();
// Return an empty string for APP in the unified case.
if ((aType == APP) && sIsUnified) {
return NS_OK;
}
nsAutoCString omniJarSpec;
if (sPath[aType]) {
nsresult rv = NS_GetURLSpecFromActualFile(sPath[aType], omniJarSpec);
if (NS_WARN_IF(NS_FAILED(rv)))
return rv;
result = "jar:";
if (sIsNested[aType])
result += "jar:";
result += omniJarSpec;
result += "!";
if (sIsNested[aType])
result += "/" NS_STRINGIFY(OMNIJAR_NAME) "!";
} else {
nsCOMPtr<nsIFile> dir;
nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile), getter_AddRefs(dir));
nsresult rv = NS_GetURLSpecFromActualFile(dir, result);
if (NS_WARN_IF(NS_FAILED(rv)))
return rv;
}
result += "/";
// Return an empty string for APP in the unified case.
if ((aType == APP) && sIsUnified) {
return NS_OK;
}
nsAutoCString omniJarSpec;
if (sPath[aType]) {
nsresult rv = NS_GetURLSpecFromActualFile(sPath[aType], omniJarSpec);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
aResult = "jar:";
if (sIsNested[aType]) {
aResult += "jar:";
}
aResult += omniJarSpec;
aResult += "!";
if (sIsNested[aType]) {
aResult += "/" NS_STRINGIFY(OMNIJAR_NAME) "!";
}
} else {
nsCOMPtr<nsIFile> dir;
nsDirectoryService::gService->Get(SPROP(aType), NS_GET_IID(nsIFile),
getter_AddRefs(dir));
nsresult rv = NS_GetURLSpecFromActualFile(dir, aResult);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
aResult += "/";
return NS_OK;
}
} /* namespace mozilla */

View File

@ -16,114 +16,108 @@ class nsIURI;
namespace mozilla {
class Omnijar {
class Omnijar
{
private:
/**
* Store an nsIFile for an omni.jar. We can store two paths here, one
* for GRE (corresponding to resource://gre/) and one for APP
* (corresponding to resource:/// and resource://app/), but only
* store one when both point to the same location (unified).
*/
static nsIFile *sPath[2];
/**
* Store an nsIFile for an omni.jar. We can store two paths here, one
* for GRE (corresponding to resource://gre/) and one for APP
* (corresponding to resource:/// and resource://app/), but only
* store one when both point to the same location (unified).
*/
static nsIFile* sPath[2];
/**
* Cached nsZipArchives for the corresponding sPath
*/
static nsZipArchive *sReader[2];
/**
* Cached nsZipArchives for the corresponding sPath
*/
static nsZipArchive* sReader[2];
/**
* Has Omnijar::Init() been called?
*/
static bool sInitialized;
/**
* Has Omnijar::Init() been called?
*/
static bool sInitialized;
public:
enum Type {
enum Type
{
GRE = 0,
APP = 1
};
};
/**
* Returns whether SetBase has been called at least once with
* a valid nsIFile
*/
static inline bool
IsInitialized()
{
return sInitialized;
}
/**
* Returns whether SetBase has been called at least once with
* a valid nsIFile
*/
static inline bool IsInitialized() { return sInitialized; }
/**
* Initializes the Omnijar API with the given directory or file for GRE and
* APP. Each of the paths given can be:
* - a file path, pointing to the omnijar file,
* - a directory path, pointing to a directory containing an "omni.jar" file,
* - nullptr for autodetection of an "omni.jar" file.
*/
static void Init(nsIFile *aGrePath = nullptr, nsIFile *aAppPath = nullptr);
/**
* Initializes the Omnijar API with the given directory or file for GRE and
* APP. Each of the paths given can be:
* - a file path, pointing to the omnijar file,
* - a directory path, pointing to a directory containing an "omni.jar" file,
* - nullptr for autodetection of an "omni.jar" file.
*/
static void Init(nsIFile* aGrePath = nullptr, nsIFile* aAppPath = nullptr);
/**
* Cleans up the Omnijar API
*/
static void CleanUp();
/**
* Cleans up the Omnijar API
*/
static void CleanUp();
/**
* Returns an nsIFile pointing to the omni.jar file for GRE or APP.
* Returns nullptr when there is no corresponding omni.jar.
* Also returns nullptr for APP in the unified case.
*/
static inline already_AddRefed<nsIFile>
GetPath(Type aType)
{
/**
* Returns an nsIFile pointing to the omni.jar file for GRE or APP.
* Returns nullptr when there is no corresponding omni.jar.
* Also returns nullptr for APP in the unified case.
*/
static inline already_AddRefed<nsIFile> GetPath(Type aType)
{
NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
nsCOMPtr<nsIFile> path = sPath[aType];
return path.forget();
}
}
/**
* Returns whether GRE or APP use an omni.jar. Returns PR_False for
* APP when using an omni.jar in the unified case.
*/
static inline bool
HasOmnijar(Type aType)
{
/**
* Returns whether GRE or APP use an omni.jar. Returns PR_False for
* APP when using an omni.jar in the unified case.
*/
static inline bool HasOmnijar(Type aType)
{
NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
return !!sPath[aType];
}
}
/**
* Returns a nsZipArchive pointer for the omni.jar file for GRE or
* APP. Returns nullptr in the same cases GetPath() would.
*/
static inline already_AddRefed<nsZipArchive>
GetReader(Type aType)
{
/**
* Returns a nsZipArchive pointer for the omni.jar file for GRE or
* APP. Returns nullptr in the same cases GetPath() would.
*/
static inline already_AddRefed<nsZipArchive> GetReader(Type aType)
{
NS_ABORT_IF_FALSE(IsInitialized(), "Omnijar not initialized");
nsRefPtr<nsZipArchive> reader = sReader[aType];
return reader.forget();
}
}
/**
* Returns a nsZipArchive pointer for the given path IAOI the given
* path is the omni.jar for either GRE or APP.
*/
static already_AddRefed<nsZipArchive> GetReader(nsIFile *aPath);
/**
* Returns a nsZipArchive pointer for the given path IAOI the given
* path is the omni.jar for either GRE or APP.
*/
static already_AddRefed<nsZipArchive> GetReader(nsIFile* aPath);
/**
* Returns the URI string corresponding to the omni.jar or directory
* for GRE or APP. i.e. jar:/path/to/omni.jar!/ for omni.jar and
* /path/to/base/dir/ otherwise. Returns an empty string for APP in
* the unified case.
* The returned URI is guaranteed to end with a slash.
*/
static nsresult GetURIString(Type aType, nsACString &result);
/**
* Returns the URI string corresponding to the omni.jar or directory
* for GRE or APP. i.e. jar:/path/to/omni.jar!/ for omni.jar and
* /path/to/base/dir/ otherwise. Returns an empty string for APP in
* the unified case.
* The returned URI is guaranteed to end with a slash.
*/
static nsresult GetURIString(Type aType, nsACString& aResult);
private:
/**
* Used internally, respectively by Init() and CleanUp()
*/
static void InitOne(nsIFile *aPath, Type aType);
static void CleanUpOne(Type aType);
/**
* Used internally, respectively by Init() and CleanUp()
*/
static void InitOne(nsIFile* aPath, Type aType);
static void CleanUpOne(Type aType);
}; /* class Omnijar */
} /* namespace mozilla */

View File

@ -13,16 +13,16 @@
MOZ_BEGIN_EXTERN_C
/** Register file descriptor to be ignored by poisoning IO interposer */
void MozillaRegisterDebugFD(int fd);
void MozillaRegisterDebugFD(int aFd);
/** Register file to be ignored by poisoning IO interposer */
void MozillaRegisterDebugFILE(FILE *f);
void MozillaRegisterDebugFILE(FILE* aFile);
/** Unregister file descriptor from being ignored by poisoning IO interposer */
void MozillaUnRegisterDebugFD(int fd);
void MozillaUnRegisterDebugFD(int aFd);
/** Unregister file from being ignored by poisoning IO interposer */
void MozillaUnRegisterDebugFILE(FILE *f);
void MozillaUnRegisterDebugFILE(FILE* aFile);
MOZ_END_EXTERN_C
@ -67,11 +67,11 @@ void ClearPoisonIOInterposer();
#ifdef __cplusplus
namespace mozilla {
inline bool IsDebugFile(intptr_t aFileID){ return true; }
inline void InitPoisonIOInterposer(){}
inline void ClearPoisonIOInterposer(){}
inline bool IsDebugFile(intptr_t aFileID) { return true; }
inline void InitPoisonIOInterposer() {}
inline void ClearPoisonIOInterposer() {}
#ifdef XP_MACOSX
inline void OnlyReportDirtyWrites(){}
inline void OnlyReportDirtyWrites() {}
#endif /* XP_MACOSX */
} // namespace mozilla
#endif /* __cplusplus */

View File

@ -15,11 +15,15 @@
// Auxiliary method to convert file descriptors to ids
#if defined(XP_WIN32)
#include <io.h>
inline intptr_t FileDescriptorToID(int aFd) {
inline intptr_t
FileDescriptorToID(int aFd)
{
return _get_osfhandle(aFd);
}
#else
inline intptr_t FileDescriptorToID(int aFd) {
inline intptr_t
FileDescriptorToID(int aFd)
{
return aFd;
}
#endif /* if not XP_WIN32 */
@ -27,21 +31,20 @@ inline intptr_t FileDescriptorToID(int aFd) {
using namespace mozilla;
namespace {
struct DebugFilesAutoLockTraits {
typedef PRLock *type;
const static type empty() {
return nullptr;
}
const static void release(type aL) {
PR_Unlock(aL);
}
struct DebugFilesAutoLockTraits
{
typedef PRLock* type;
const static type empty() { return nullptr; }
const static void release(type aL) { PR_Unlock(aL); }
};
class DebugFilesAutoLock : public Scoped<DebugFilesAutoLockTraits> {
static PRLock *Lock;
class DebugFilesAutoLock : public Scoped<DebugFilesAutoLockTraits>
{
static PRLock* Lock;
public:
static void Clear();
static PRLock *getDebugFileIDsLock() {
static PRLock* getDebugFileIDsLock()
{
// On windows this static is not thread safe, but we know that the first
// call is from
// * An early registration of a debug FD or
@ -57,38 +60,45 @@ public:
return Lock;
}
DebugFilesAutoLock() :
Scoped<DebugFilesAutoLockTraits>(getDebugFileIDsLock()) {
DebugFilesAutoLock()
: Scoped<DebugFilesAutoLockTraits>(getDebugFileIDsLock())
{
PR_Lock(get());
}
};
PRLock *DebugFilesAutoLock::Lock;
void DebugFilesAutoLock::Clear() {
PRLock* DebugFilesAutoLock::Lock;
void
DebugFilesAutoLock::Clear()
{
MOZ_ASSERT(Lock != nullptr);
Lock = nullptr;
}
// Return a vector used to hold the IDs of the current debug files. On unix
// an ID is a file descriptor. On Windows it is a file HANDLE.
std::vector<intptr_t>* getDebugFileIDs() {
std::vector<intptr_t>*
getDebugFileIDs()
{
PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(DebugFilesAutoLock::getDebugFileIDsLock());
// We have to use new as some write happen during static destructors
// so an static std::vector might be destroyed while we still need it.
static std::vector<intptr_t> *DebugFileIDs = new std::vector<intptr_t>();
static std::vector<intptr_t>* DebugFileIDs = new std::vector<intptr_t>();
return DebugFileIDs;
}
} // anonymous namespace
namespace mozilla{
namespace mozilla {
// Auxiliary Method to test if a file descriptor is registered to be ignored
// by the poisoning IO interposer
bool IsDebugFile(intptr_t aFileID) {
bool
IsDebugFile(intptr_t aFileID)
{
DebugFilesAutoLock lockedScope;
std::vector<intptr_t> &Vec = *getDebugFileIDs();
std::vector<intptr_t>& Vec = *getDebugFileIDs();
return std::find(Vec.begin(), Vec.end(), aFileID) != Vec.end();
}
@ -112,39 +122,47 @@ bool IsDebugFile(intptr_t aFileID) {
extern "C" {
void MozillaRegisterDebugFD(int fd) {
intptr_t fileId = FileDescriptorToID(fd);
DebugFilesAutoLock lockedScope;
std::vector<intptr_t> &Vec = *getDebugFileIDs();
MOZ_ASSERT(std::find(Vec.begin(), Vec.end(), fileId) == Vec.end());
Vec.push_back(fileId);
}
void
MozillaRegisterDebugFD(int aFd)
{
intptr_t fileId = FileDescriptorToID(aFd);
DebugFilesAutoLock lockedScope;
std::vector<intptr_t>& Vec = *getDebugFileIDs();
MOZ_ASSERT(std::find(Vec.begin(), Vec.end(), fileId) == Vec.end());
Vec.push_back(fileId);
}
void MozillaRegisterDebugFILE(FILE *f) {
int fd = fileno(f);
if (fd == 1 || fd == 2) {
return;
}
MozillaRegisterDebugFD(fd);
void
MozillaRegisterDebugFILE(FILE* aFile)
{
int fd = fileno(aFile);
if (fd == 1 || fd == 2) {
return;
}
MozillaRegisterDebugFD(fd);
}
void MozillaUnRegisterDebugFD(int fd) {
DebugFilesAutoLock lockedScope;
intptr_t fileId = FileDescriptorToID(fd);
std::vector<intptr_t> &Vec = *getDebugFileIDs();
std::vector<intptr_t>::iterator i =
std::find(Vec.begin(), Vec.end(), fileId);
MOZ_ASSERT(i != Vec.end());
Vec.erase(i);
void
MozillaUnRegisterDebugFD(int aFd)
{
DebugFilesAutoLock lockedScope;
intptr_t fileId = FileDescriptorToID(aFd);
std::vector<intptr_t>& Vec = *getDebugFileIDs();
std::vector<intptr_t>::iterator i =
std::find(Vec.begin(), Vec.end(), fileId);
MOZ_ASSERT(i != Vec.end());
Vec.erase(i);
}
void
MozillaUnRegisterDebugFILE(FILE* aFile)
{
int fd = fileno(aFile);
if (fd == 1 || fd == 2) {
return;
}
fflush(aFile);
MozillaUnRegisterDebugFD(fd);
}
void MozillaUnRegisterDebugFILE(FILE *f) {
int fd = fileno(f);
if (fd == 1 || fd == 2) {
return;
}
fflush(f);
MozillaUnRegisterDebugFD(fd);
}
}
} // extern "C"

View File

@ -43,8 +43,8 @@ static bool sIsEnabled = false;
static bool sOnlyReportDirtyWrites = false;
// Routines for write validation
bool IsValidWrite(int fd, const void *wbuf, size_t count);
bool IsIPCWrite(int fd, const struct stat &buf);
bool IsValidWrite(int aFd, const void* aWbuf, size_t aCount);
bool IsIPCWrite(int aFd, const struct stat& aBuf);
/******************************** IO AutoTimer ********************************/
@ -65,7 +65,7 @@ public:
}
MacIOAutoObservation(IOInterposeObserver::Operation aOp, int aFd,
const void *aBuf, size_t aCount)
const void* aBuf, size_t aCount)
: IOInterposeObserver::Observation(aOp, sReference, sIsEnabled &&
!IsDebugFile(aFd) &&
IsValidWrite(aFd, aBuf, aCount))
@ -97,7 +97,8 @@ private:
const char* MacIOAutoObservation::sReference = "PoisonIOInterposer";
// Get filename for this observation
const char16_t* MacIOAutoObservation::Filename()
const char16_t*
MacIOAutoObservation::Filename()
{
// If mHasQueriedFilename is true, then we already have it
if (mHasQueriedFilename) {
@ -119,52 +120,55 @@ const char16_t* MacIOAutoObservation::Filename()
// We want to detect "actual" writes, not IPC. Some IPC mechanisms are
// implemented with file descriptors, so filter them out.
bool IsIPCWrite(int fd, const struct stat &buf) {
if ((buf.st_mode & S_IFMT) == S_IFIFO) {
bool
IsIPCWrite(int aFd, const struct stat& aBuf)
{
if ((aBuf.st_mode & S_IFMT) == S_IFIFO) {
return true;
}
if ((buf.st_mode & S_IFMT) != S_IFSOCK) {
if ((aBuf.st_mode & S_IFMT) != S_IFSOCK) {
return false;
}
sockaddr_storage address;
socklen_t len = sizeof(address);
if (getsockname(fd, (sockaddr*) &address, &len) != 0) {
return true; // Ignore the fd if we can't find what it is.
if (getsockname(aFd, (sockaddr*)&address, &len) != 0) {
return true; // Ignore the aFd if we can't find what it is.
}
return address.ss_family == AF_UNIX;
}
// We want to report actual disk IO not things that don't move bits on the disk
bool IsValidWrite(int fd, const void *wbuf, size_t count)
bool
IsValidWrite(int aFd, const void* aWbuf, size_t aCount)
{
// Ignore writes of zero bytes, Firefox does some during shutdown.
if (count == 0) {
if (aCount == 0) {
return false;
}
{
struct stat buf;
int rv = fstat(fd, &buf);
int rv = fstat(aFd, &buf);
if (rv != 0) {
return true;
}
if (IsIPCWrite(fd, buf)) {
if (IsIPCWrite(aFd, buf)) {
return false;
}
}
// For writev we pass a nullptr wbuf. We should only get here from
// dbm, and it uses write, so assert that we have wbuf.
if (!wbuf) {
// For writev we pass a nullptr aWbuf. We should only get here from
// dbm, and it uses write, so assert that we have aWbuf.
if (!aWbuf) {
return true;
}
// Break, here if we're allowed to report non-dirty writes
if(!sOnlyReportDirtyWrites) {
if (!sOnlyReportDirtyWrites) {
return true;
}
@ -172,23 +176,23 @@ bool IsValidWrite(int fd, const void *wbuf, size_t count)
// content. This is needed because dbm doesn't keep track of dirty bits
// and can end up writing the same data to disk twice. Once when the
// user (nss) asks it to sync and once when closing the database.
ScopedFreePtr<void> wbuf2(malloc(count));
ScopedFreePtr<void> wbuf2(malloc(aCount));
if (!wbuf2) {
return true;
}
off_t pos = lseek(fd, 0, SEEK_CUR);
off_t pos = lseek(aFd, 0, SEEK_CUR);
if (pos == -1) {
return true;
}
ssize_t r = read(fd, wbuf2, count);
if (r < 0 || (size_t)r != count) {
ssize_t r = read(aFd, wbuf2, aCount);
if (r < 0 || (size_t)r != aCount) {
return true;
}
int cmp = memcmp(wbuf, wbuf2, count);
int cmp = memcmp(aWbuf, wbuf2, aCount);
if (cmp != 0) {
return true;
}
off_t pos2 = lseek(fd, pos, SEEK_SET);
off_t pos2 = lseek(aFd, pos, SEEK_SET);
if (pos2 != pos) {
return true;
}
@ -200,33 +204,40 @@ bool IsValidWrite(int fd, const void *wbuf, size_t count)
/*************************** Function Interception ***************************/
/** Structure for declaration of function override */
struct FuncData {
const char *Name; // Name of the function for the ones we use dlsym
const void *Wrapper; // The function that we will replace 'Function' with
void *Function; // The function that will be replaced with 'Wrapper'
void *Buffer; // Will point to the jump buffer that lets us call
struct FuncData
{
const char* Name; // Name of the function for the ones we use dlsym
const void* Wrapper; // The function that we will replace 'Function' with
void* Function; // The function that will be replaced with 'Wrapper'
void* Buffer; // Will point to the jump buffer that lets us call
// 'Function' after it has been replaced.
};
// Wrap aio_write. We have not seen it before, so just assert/report it.
typedef ssize_t (*aio_write_t)(struct aiocb *aiocbp);
ssize_t wrap_aio_write(struct aiocb *aiocbp);
FuncData aio_write_data = { 0, (void*) wrap_aio_write, (void*) aio_write };
ssize_t wrap_aio_write(struct aiocb *aiocbp) {
MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aiocbp->aio_fildes);
typedef ssize_t (*aio_write_t)(struct aiocb* aAioCbp);
ssize_t wrap_aio_write(struct aiocb* aAioCbp);
FuncData aio_write_data = { 0, (void*)wrap_aio_write, (void*)aio_write };
ssize_t
wrap_aio_write(struct aiocb* aAioCbp)
{
MacIOAutoObservation timer(IOInterposeObserver::OpWrite,
aAioCbp->aio_fildes);
aio_write_t old_write = (aio_write_t) aio_write_data.Buffer;
return old_write(aiocbp);
aio_write_t old_write = (aio_write_t)aio_write_data.Buffer;
return old_write(aAioCbp);
}
// Wrap pwrite-like functions.
// We have not seen them before, so just assert/report it.
typedef ssize_t (*pwrite_t)(int fd, const void *buf, size_t nbyte, off_t offset);
template<FuncData &foo>
ssize_t wrap_pwrite_temp(int fd, const void *buf, size_t nbyte, off_t offset) {
MacIOAutoObservation timer(IOInterposeObserver::OpWrite, fd);
pwrite_t old_write = (pwrite_t) foo.Buffer;
return old_write(fd, buf, nbyte, offset);
typedef ssize_t (*pwrite_t)(int aFd, const void* buf, size_t aNumBytes,
off_t aOffset);
template<FuncData& foo>
ssize_t
wrap_pwrite_temp(int aFd, const void* aBuf, size_t aNumBytes, off_t aOffset)
{
MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd);
pwrite_t old_write = (pwrite_t)foo.Buffer;
return old_write(aFd, aBuf, aNumBytes, aOffset);
}
// Define a FuncData for a pwrite-like functions.
@ -242,12 +253,15 @@ DEFINE_PWRITE_DATA(pwrite_UNIX2003, "pwrite$UNIX2003");
DEFINE_PWRITE_DATA(pwrite_NOCANCEL, "pwrite$NOCANCEL");
typedef ssize_t (*writev_t)(int fd, const struct iovec *iov, int iovcnt);
template<FuncData &foo>
ssize_t wrap_writev_temp(int fd, const struct iovec *iov, int iovcnt) {
MacIOAutoObservation timer(IOInterposeObserver::OpWrite, fd, nullptr, iovcnt);
writev_t old_write = (writev_t) foo.Buffer;
return old_write(fd, iov, iovcnt);
typedef ssize_t (*writev_t)(int aFd, const struct iovec* aIov, int aIovCount);
template<FuncData& foo>
ssize_t
wrap_writev_temp(int aFd, const struct iovec* aIov, int aIovCount)
{
MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd, nullptr,
aIovCount);
writev_t old_write = (writev_t)foo.Buffer;
return old_write(aFd, aIov, aIovCount);
}
// Define a FuncData for a writev-like functions.
@ -262,12 +276,14 @@ DEFINE_WRITEV_DATA(writev_UNIX2003, "writev$UNIX2003");
// This exists on 64 bit OS X
DEFINE_WRITEV_DATA(writev_NOCANCEL, "writev$NOCANCEL");
typedef ssize_t (*write_t)(int fd, const void *buf, size_t count);
template<FuncData &foo>
ssize_t wrap_write_temp(int fd, const void *buf, size_t count) {
MacIOAutoObservation timer(IOInterposeObserver::OpWrite, fd, buf, count);
write_t old_write = (write_t) foo.Buffer;
return old_write(fd, buf, count);
typedef ssize_t (*write_t)(int aFd, const void* aBuf, size_t aCount);
template<FuncData& foo>
ssize_t
wrap_write_temp(int aFd, const void* aBuf, size_t aCount)
{
MacIOAutoObservation timer(IOInterposeObserver::OpWrite, aFd, aBuf, aCount);
write_t old_write = (write_t)foo.Buffer;
return old_write(aFd, aBuf, aCount);
}
// Define a FuncData for a write-like functions.
@ -282,22 +298,24 @@ DEFINE_WRITE_DATA(write_UNIX2003, "write$UNIX2003");
// This exists on 64 bit OS X
DEFINE_WRITE_DATA(write_NOCANCEL, "write$NOCANCEL");
FuncData *Functions[] = { &aio_write_data,
FuncData* Functions[] = {
&aio_write_data,
&pwrite_data,
&pwrite_NOCANCEL_UNIX2003_data,
&pwrite_UNIX2003_data,
&pwrite_NOCANCEL_data,
&pwrite_data,
&pwrite_NOCANCEL_UNIX2003_data,
&pwrite_UNIX2003_data,
&pwrite_NOCANCEL_data,
&write_data,
&write_NOCANCEL_UNIX2003_data,
&write_UNIX2003_data,
&write_NOCANCEL_data,
&write_data,
&write_NOCANCEL_UNIX2003_data,
&write_UNIX2003_data,
&write_NOCANCEL_data,
&writev_data,
&writev_NOCANCEL_UNIX2003_data,
&writev_UNIX2003_data,
&writev_NOCANCEL_data};
&writev_data,
&writev_NOCANCEL_UNIX2003_data,
&writev_UNIX2003_data,
&writev_NOCANCEL_data
};
const int NumFunctions = ArrayLength(Functions);
@ -307,7 +325,9 @@ const int NumFunctions = ArrayLength(Functions);
namespace mozilla {
void InitPoisonIOInterposer() {
void
InitPoisonIOInterposer()
{
// Enable reporting from poisoned write methods
sIsEnabled = true;
@ -323,7 +343,7 @@ void InitPoisonIOInterposer() {
MozillaRegisterDebugFD(2);
for (int i = 0; i < NumFunctions; ++i) {
FuncData *d = Functions[i];
FuncData* d = Functions[i];
if (!d->Function) {
d->Function = dlsym(RTLD_DEFAULT, d->Name);
}
@ -331,16 +351,20 @@ void InitPoisonIOInterposer() {
continue;
}
DebugOnly<mach_error_t> t = mach_override_ptr(d->Function, d->Wrapper,
&d->Buffer);
&d->Buffer);
MOZ_ASSERT(t == err_none);
}
}
void OnlyReportDirtyWrites() {
void
OnlyReportDirtyWrites()
{
sOnlyReportDirtyWrites = true;
}
void ClearPoisonIOInterposer() {
void
ClearPoisonIOInterposer()
{
// Not sure how or if we can unpoison the functions. Would be nice, but no
// worries we won't need to do this anyway.
sIsEnabled = false;

View File

@ -8,9 +8,9 @@
extern "C" {
void MozillaRegisterDebugFD(int fd) {}
void MozillaRegisterDebugFILE(FILE *f) {}
void MozillaUnRegisterDebugFD(int fd) {}
void MozillaUnRegisterDebugFILE(FILE *f) {}
void MozillaRegisterDebugFD(int aFd) {}
void MozillaRegisterDebugFILE(FILE* aFile) {}
void MozillaUnRegisterDebugFD(int aFd) {}
void MozillaUnRegisterDebugFILE(FILE* aFile) {}
}
} // extern "C"

View File

@ -39,103 +39,96 @@ static bool sIOPoisoned = false;
* Function pointer declaration for internal NT routine to create/open files.
* For documentation on the NtCreateFile routine, see MSDN.
*/
typedef NTSTATUS (NTAPI *NtCreateFileFn)(
OUT PHANDLE aFileHandle,
IN ACCESS_MASK aDesiredAccess,
IN POBJECT_ATTRIBUTES aObjectAttributes,
OUT PIO_STATUS_BLOCK aIoStatusBlock,
IN PLARGE_INTEGER aAllocationSize,
IN ULONG aFileAttributes,
IN ULONG aShareAccess,
IN ULONG aCreateDisposition,
IN ULONG aCreateOptions,
IN PVOID aEaBuffer,
IN ULONG aEaLength
);
typedef NTSTATUS (NTAPI* NtCreateFileFn)(
PHANDLE aFileHandle,
ACCESS_MASK aDesiredAccess,
POBJECT_ATTRIBUTES aObjectAttributes,
PIO_STATUS_BLOCK aIoStatusBlock,
PLARGE_INTEGER aAllocationSize,
ULONG aFileAttributes,
ULONG aShareAccess,
ULONG aCreateDisposition,
ULONG aCreateOptions,
PVOID aEaBuffer,
ULONG aEaLength);
/**
* Function pointer declaration for internal NT routine to read data from file.
* For documentation on the NtReadFile routine, see ZwReadFile on MSDN.
*/
typedef NTSTATUS (NTAPI *NtReadFileFn)(
IN HANDLE aFileHandle,
IN HANDLE aEvent,
IN PIO_APC_ROUTINE aApc,
IN PVOID aApcCtx,
OUT PIO_STATUS_BLOCK aIoStatus,
OUT PVOID aBuffer,
IN ULONG aLength,
IN PLARGE_INTEGER aOffset,
IN PULONG aKey
);
typedef NTSTATUS (NTAPI* NtReadFileFn)(
HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
PVOID aBuffer,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey);
/**
* Function pointer declaration for internal NT routine to read data from file.
* No documentation exists, see wine sources for details.
*/
typedef NTSTATUS (NTAPI* NtReadFileScatterFn)(
IN HANDLE aFileHandle,
IN HANDLE aEvent,
IN PIO_APC_ROUTINE aApc,
IN PVOID aApcCtx,
OUT PIO_STATUS_BLOCK aIoStatus,
IN FILE_SEGMENT_ELEMENT* aSegments,
IN ULONG aLength,
IN PLARGE_INTEGER aOffset,
IN PULONG aKey
);
HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
FILE_SEGMENT_ELEMENT* aSegments,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey);
/**
* Function pointer declaration for internal NT routine to write data to file.
* For documentation on the NtWriteFile routine, see ZwWriteFile on MSDN.
*/
typedef NTSTATUS (NTAPI *NtWriteFileFn)(
IN HANDLE aFileHandle,
IN HANDLE aEvent,
IN PIO_APC_ROUTINE aApc,
IN PVOID aApcCtx,
OUT PIO_STATUS_BLOCK aIoStatus,
IN PVOID aBuffer,
IN ULONG aLength,
IN PLARGE_INTEGER aOffset,
IN PULONG aKey
);
typedef NTSTATUS (NTAPI* NtWriteFileFn)(
HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
PVOID aBuffer,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey);
/**
* Function pointer declaration for internal NT routine to write data to file.
* No documentation exists, see wine sources for details.
*/
typedef NTSTATUS (NTAPI *NtWriteFileGatherFn)(
IN HANDLE aFileHandle,
IN HANDLE aEvent,
IN PIO_APC_ROUTINE aApc,
IN PVOID aApcCtx,
OUT PIO_STATUS_BLOCK aIoStatus,
IN FILE_SEGMENT_ELEMENT* aSegments,
IN ULONG aLength,
IN PLARGE_INTEGER aOffset,
IN PULONG aKey
);
typedef NTSTATUS (NTAPI* NtWriteFileGatherFn)(
HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
FILE_SEGMENT_ELEMENT* aSegments,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey);
/**
* Function pointer declaration for internal NT routine to flush to disk.
* For documentation on the NtFlushBuffersFile routine, see ZwFlushBuffersFile
* on MSDN.
*/
typedef NTSTATUS (NTAPI *NtFlushBuffersFileFn)(
IN HANDLE aFileHandle,
OUT PIO_STATUS_BLOCK aIoStatusBlock
);
typedef NTSTATUS (NTAPI* NtFlushBuffersFileFn)(
HANDLE aFileHandle,
PIO_STATUS_BLOCK aIoStatusBlock);
typedef struct _FILE_NETWORK_OPEN_INFORMATION* PFILE_NETWORK_OPEN_INFORMATION;
/**
* Function pointer delaration for internal NT routine to query file attributes.
* (equivalent to stat)
*/
typedef NTSTATUS (NTAPI *NtQueryFullAttributesFileFn)(
IN POBJECT_ATTRIBUTES aObjectAttributes,
OUT PFILE_NETWORK_OPEN_INFORMATION aFileInformation
);
typedef NTSTATUS (NTAPI* NtQueryFullAttributesFileFn)(
POBJECT_ATTRIBUTES aObjectAttributes,
PFILE_NETWORK_OPEN_INFORMATION aFileInformation);
/*************************** Auxiliary Declarations ***************************/
@ -148,9 +141,8 @@ class WinIOAutoObservation : public IOInterposeObserver::Observation
public:
WinIOAutoObservation(IOInterposeObserver::Operation aOp,
HANDLE aFileHandle, const LARGE_INTEGER* aOffset)
: IOInterposeObserver::Observation(aOp, sReference,
!IsDebugFile(reinterpret_cast<intptr_t>(
aFileHandle)))
: IOInterposeObserver::Observation(
aOp, sReference, !IsDebugFile(reinterpret_cast<intptr_t>(aFileHandle)))
, mFileHandle(aFileHandle)
, mHasQueriedFilename(false)
, mFilename(nullptr)
@ -200,7 +192,8 @@ private:
const char* WinIOAutoObservation::sReference = "PoisonIOInterposer";
// Get filename for this observation
const char16_t* WinIOAutoObservation::Filename()
const char16_t*
WinIOAutoObservation::Filename()
{
// If mHasQueriedFilename is true, then filename is already stored in mFilename
if (mHasQueriedFilename) {
@ -213,7 +206,7 @@ const char16_t* WinIOAutoObservation::Filename()
mFilename = ToNewUnicode(utf16Filename);
}
mHasQueriedFilename = true;
// Return filename
return mFilename;
}
@ -229,27 +222,25 @@ static NtWriteFileGatherFn gOriginalNtWriteFileGather;
static NtFlushBuffersFileFn gOriginalNtFlushBuffersFile;
static NtQueryFullAttributesFileFn gOriginalNtQueryFullAttributesFile;
static NTSTATUS NTAPI InterposedNtCreateFile(
PHANDLE aFileHandle,
ACCESS_MASK aDesiredAccess,
POBJECT_ATTRIBUTES aObjectAttributes,
PIO_STATUS_BLOCK aIoStatusBlock,
PLARGE_INTEGER aAllocationSize,
ULONG aFileAttributes,
ULONG aShareAccess,
ULONG aCreateDisposition,
ULONG aCreateOptions,
PVOID aEaBuffer,
ULONG aEaLength
)
static NTSTATUS NTAPI
InterposedNtCreateFile(PHANDLE aFileHandle,
ACCESS_MASK aDesiredAccess,
POBJECT_ATTRIBUTES aObjectAttributes,
PIO_STATUS_BLOCK aIoStatusBlock,
PLARGE_INTEGER aAllocationSize,
ULONG aFileAttributes,
ULONG aShareAccess,
ULONG aCreateDisposition,
ULONG aCreateOptions,
PVOID aEaBuffer,
ULONG aEaLength)
{
// Report IO
const wchar_t* buf = aObjectAttributes ?
aObjectAttributes->ObjectName->Buffer :
L"";
uint32_t len = aObjectAttributes ?
aObjectAttributes->ObjectName->Length / sizeof(WCHAR) :
0;
const wchar_t* buf =
aObjectAttributes ? aObjectAttributes->ObjectName->Buffer : L"";
uint32_t len =
aObjectAttributes ? aObjectAttributes->ObjectName->Length / sizeof(WCHAR) :
0;
nsDependentSubstring filename(buf, len);
WinIOAutoObservation timer(IOInterposeObserver::OpCreateOrOpen, filename);
@ -257,31 +248,29 @@ static NTSTATUS NTAPI InterposedNtCreateFile(
MOZ_ASSERT(gOriginalNtCreateFile);
// Execute original function
return gOriginalNtCreateFile(
aFileHandle,
aDesiredAccess,
aObjectAttributes,
aIoStatusBlock,
aAllocationSize,
aFileAttributes,
aShareAccess,
aCreateDisposition,
aCreateOptions,
aEaBuffer,
aEaLength
);
return gOriginalNtCreateFile(aFileHandle,
aDesiredAccess,
aObjectAttributes,
aIoStatusBlock,
aAllocationSize,
aFileAttributes,
aShareAccess,
aCreateDisposition,
aCreateOptions,
aEaBuffer,
aEaLength);
}
static NTSTATUS NTAPI InterposedNtReadFile(
HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
PVOID aBuffer,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey)
static NTSTATUS NTAPI
InterposedNtReadFile(HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
PVOID aBuffer,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey)
{
// Report IO
WinIOAutoObservation timer(IOInterposeObserver::OpRead, aFileHandle, aOffset);
@ -290,29 +279,27 @@ static NTSTATUS NTAPI InterposedNtReadFile(
MOZ_ASSERT(gOriginalNtReadFile);
// Execute original function
return gOriginalNtReadFile(
aFileHandle,
aEvent,
aApc,
aApcCtx,
aIoStatus,
aBuffer,
aLength,
aOffset,
aKey
);
return gOriginalNtReadFile(aFileHandle,
aEvent,
aApc,
aApcCtx,
aIoStatus,
aBuffer,
aLength,
aOffset,
aKey);
}
static NTSTATUS NTAPI InterposedNtReadFileScatter(
HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
FILE_SEGMENT_ELEMENT* aSegments,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey)
static NTSTATUS NTAPI
InterposedNtReadFileScatter(HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
FILE_SEGMENT_ELEMENT* aSegments,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey)
{
// Report IO
WinIOAutoObservation timer(IOInterposeObserver::OpRead, aFileHandle, aOffset);
@ -321,30 +308,28 @@ static NTSTATUS NTAPI InterposedNtReadFileScatter(
MOZ_ASSERT(gOriginalNtReadFileScatter);
// Execute original function
return gOriginalNtReadFileScatter(
aFileHandle,
aEvent,
aApc,
aApcCtx,
aIoStatus,
aSegments,
aLength,
aOffset,
aKey
);
return gOriginalNtReadFileScatter(aFileHandle,
aEvent,
aApc,
aApcCtx,
aIoStatus,
aSegments,
aLength,
aOffset,
aKey);
}
// Interposed NtWriteFile function
static NTSTATUS NTAPI InterposedNtWriteFile(
HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
PVOID aBuffer,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey)
static NTSTATUS NTAPI
InterposedNtWriteFile(HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
PVOID aBuffer,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey)
{
// Report IO
WinIOAutoObservation timer(IOInterposeObserver::OpWrite, aFileHandle,
@ -354,30 +339,28 @@ static NTSTATUS NTAPI InterposedNtWriteFile(
MOZ_ASSERT(gOriginalNtWriteFile);
// Execute original function
return gOriginalNtWriteFile(
aFileHandle,
aEvent,
aApc,
aApcCtx,
aIoStatus,
aBuffer,
aLength,
aOffset,
aKey
);
return gOriginalNtWriteFile(aFileHandle,
aEvent,
aApc,
aApcCtx,
aIoStatus,
aBuffer,
aLength,
aOffset,
aKey);
}
// Interposed NtWriteFileGather function
static NTSTATUS NTAPI InterposedNtWriteFileGather(
HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
FILE_SEGMENT_ELEMENT* aSegments,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey)
static NTSTATUS NTAPI
InterposedNtWriteFileGather(HANDLE aFileHandle,
HANDLE aEvent,
PIO_APC_ROUTINE aApc,
PVOID aApcCtx,
PIO_STATUS_BLOCK aIoStatus,
FILE_SEGMENT_ELEMENT* aSegments,
ULONG aLength,
PLARGE_INTEGER aOffset,
PULONG aKey)
{
// Report IO
WinIOAutoObservation timer(IOInterposeObserver::OpWrite, aFileHandle,
@ -387,22 +370,20 @@ static NTSTATUS NTAPI InterposedNtWriteFileGather(
MOZ_ASSERT(gOriginalNtWriteFileGather);
// Execute original function
return gOriginalNtWriteFileGather(
aFileHandle,
aEvent,
aApc,
aApcCtx,
aIoStatus,
aSegments,
aLength,
aOffset,
aKey
);
return gOriginalNtWriteFileGather(aFileHandle,
aEvent,
aApc,
aApcCtx,
aIoStatus,
aSegments,
aLength,
aOffset,
aKey);
}
static NTSTATUS NTAPI InterposedNtFlushBuffersFile(
HANDLE aFileHandle,
PIO_STATUS_BLOCK aIoStatusBlock)
static NTSTATUS NTAPI
InterposedNtFlushBuffersFile(HANDLE aFileHandle,
PIO_STATUS_BLOCK aIoStatusBlock)
{
// Report IO
WinIOAutoObservation timer(IOInterposeObserver::OpFSync, aFileHandle,
@ -412,23 +393,21 @@ static NTSTATUS NTAPI InterposedNtFlushBuffersFile(
MOZ_ASSERT(gOriginalNtFlushBuffersFile);
// Execute original function
return gOriginalNtFlushBuffersFile(
aFileHandle,
aIoStatusBlock
);
return gOriginalNtFlushBuffersFile(aFileHandle,
aIoStatusBlock);
}
static NTSTATUS NTAPI InterposedNtQueryFullAttributesFile(
POBJECT_ATTRIBUTES aObjectAttributes,
PFILE_NETWORK_OPEN_INFORMATION aFileInformation)
static NTSTATUS NTAPI
InterposedNtQueryFullAttributesFile(
POBJECT_ATTRIBUTES aObjectAttributes,
PFILE_NETWORK_OPEN_INFORMATION aFileInformation)
{
// Report IO
const wchar_t* buf = aObjectAttributes ?
aObjectAttributes->ObjectName->Buffer :
L"";
uint32_t len = aObjectAttributes ?
aObjectAttributes->ObjectName->Length / sizeof(WCHAR) :
0;
const wchar_t* buf =
aObjectAttributes ? aObjectAttributes->ObjectName->Buffer : L"";
uint32_t len =
aObjectAttributes ? aObjectAttributes->ObjectName->Length / sizeof(WCHAR) :
0;
nsDependentSubstring filename(buf, len);
WinIOAutoObservation timer(IOInterposeObserver::OpStat, filename);
@ -436,10 +415,8 @@ static NTSTATUS NTAPI InterposedNtQueryFullAttributesFile(
MOZ_ASSERT(gOriginalNtQueryFullAttributesFile);
// Execute original function
return gOriginalNtQueryFullAttributesFile(
aObjectAttributes,
aFileInformation
);
return gOriginalNtQueryFullAttributesFile(aObjectAttributes,
aFileInformation);
}
} // anonymous namespace
@ -451,7 +428,9 @@ static WindowsDllInterceptor sNtDllInterceptor;
namespace mozilla {
void InitPoisonIOInterposer() {
void
InitPoisonIOInterposer()
{
// Don't poison twice... as this function may only be invoked on the main
// thread when no other threads are running, it safe to allow multiple calls
// to InitPoisonIOInterposer() without complaining (ie. failing assertions).
@ -469,41 +448,36 @@ void InitPoisonIOInterposer() {
sNtDllInterceptor.AddHook(
"NtCreateFile",
reinterpret_cast<intptr_t>(InterposedNtCreateFile),
reinterpret_cast<void**>(&gOriginalNtCreateFile)
);
reinterpret_cast<void**>(&gOriginalNtCreateFile));
sNtDllInterceptor.AddHook(
"NtReadFile",
reinterpret_cast<intptr_t>(InterposedNtReadFile),
reinterpret_cast<void**>(&gOriginalNtReadFile)
);
reinterpret_cast<void**>(&gOriginalNtReadFile));
sNtDllInterceptor.AddHook(
"NtReadFileScatter",
reinterpret_cast<intptr_t>(InterposedNtReadFileScatter),
reinterpret_cast<void**>(&gOriginalNtReadFileScatter)
);
reinterpret_cast<void**>(&gOriginalNtReadFileScatter));
sNtDllInterceptor.AddHook(
"NtWriteFile",
reinterpret_cast<intptr_t>(InterposedNtWriteFile),
reinterpret_cast<void**>(&gOriginalNtWriteFile)
);
reinterpret_cast<void**>(&gOriginalNtWriteFile));
sNtDllInterceptor.AddHook(
"NtWriteFileGather",
reinterpret_cast<intptr_t>(InterposedNtWriteFileGather),
reinterpret_cast<void**>(&gOriginalNtWriteFileGather)
);
reinterpret_cast<void**>(&gOriginalNtWriteFileGather));
sNtDllInterceptor.AddHook(
"NtFlushBuffersFile",
reinterpret_cast<intptr_t>(InterposedNtFlushBuffersFile),
reinterpret_cast<void**>(&gOriginalNtFlushBuffersFile)
);
reinterpret_cast<void**>(&gOriginalNtFlushBuffersFile));
sNtDllInterceptor.AddHook(
"NtQueryFullAttributesFile",
reinterpret_cast<intptr_t>(InterposedNtQueryFullAttributesFile),
reinterpret_cast<void**>(&gOriginalNtQueryFullAttributesFile)
);
reinterpret_cast<void**>(&gOriginalNtQueryFullAttributesFile));
}
void ClearPoisonIOInterposer() {
void
ClearPoisonIOInterposer()
{
MOZ_ASSERT(false);
if (sIOPoisoned) {
// Destroy the DLL interceptor

View File

@ -4,25 +4,36 @@
// IWYU pragma: private, include "mozilla/Services.h"
#ifdef ACCESSIBILITY
MOZ_SERVICE(AccessibilityService, nsIAccessibilityService, "@mozilla.org/accessibilityService;1")
MOZ_SERVICE(AccessibilityService, nsIAccessibilityService,
"@mozilla.org/accessibilityService;1")
#endif
MOZ_SERVICE(ChromeRegistryService, nsIChromeRegistry, "@mozilla.org/chrome/chrome-registry;1")
MOZ_SERVICE(ToolkitChromeRegistryService, nsIToolkitChromeRegistry, "@mozilla.org/chrome/chrome-registry;1")
MOZ_SERVICE(XULChromeRegistryService, nsIXULChromeRegistry, "@mozilla.org/chrome/chrome-registry;1")
MOZ_SERVICE(XULOverlayProviderService, nsIXULOverlayProvider, "@mozilla.org/chrome/chrome-registry;1")
MOZ_SERVICE(IOService, nsIIOService, "@mozilla.org/network/io-service;1")
MOZ_SERVICE(ObserverService, nsIObserverService, "@mozilla.org/observer-service;1")
MOZ_SERVICE(StringBundleService, nsIStringBundleService, "@mozilla.org/intl/stringbundle;1")
MOZ_SERVICE(XPConnect, nsIXPConnect, "@mozilla.org/js/xpc/XPConnect;1")
MOZ_SERVICE(InDOMUtils, inIDOMUtils, "@mozilla.org/inspector/dom-utils;1")
MOZ_SERVICE(PermissionManager, nsIPermissionManager, "@mozilla.org/permissionmanager;1");
MOZ_SERVICE(ChromeRegistryService, nsIChromeRegistry,
"@mozilla.org/chrome/chrome-registry;1")
MOZ_SERVICE(ToolkitChromeRegistryService, nsIToolkitChromeRegistry,
"@mozilla.org/chrome/chrome-registry;1")
MOZ_SERVICE(XULChromeRegistryService, nsIXULChromeRegistry,
"@mozilla.org/chrome/chrome-registry;1")
MOZ_SERVICE(XULOverlayProviderService, nsIXULOverlayProvider,
"@mozilla.org/chrome/chrome-registry;1")
MOZ_SERVICE(IOService, nsIIOService,
"@mozilla.org/network/io-service;1")
MOZ_SERVICE(ObserverService, nsIObserverService,
"@mozilla.org/observer-service;1")
MOZ_SERVICE(StringBundleService, nsIStringBundleService,
"@mozilla.org/intl/stringbundle;1")
MOZ_SERVICE(XPConnect, nsIXPConnect,
"@mozilla.org/js/xpc/XPConnect;1")
MOZ_SERVICE(InDOMUtils, inIDOMUtils,
"@mozilla.org/inspector/dom-utils;1")
MOZ_SERVICE(PermissionManager, nsIPermissionManager,
"@mozilla.org/permissionmanager;1");
#ifdef MOZ_USE_NAMESPACE
namespace mozilla
{
namespace mozilla {
#endif
MOZ_SERVICE(HistoryService, IHistory, "@mozilla.org/browser/history;1")
MOZ_SERVICE(HistoryService, IHistory,
"@mozilla.org/browser/history;1")
#ifdef MOZ_USE_NAMESPACE
}

View File

@ -59,7 +59,7 @@ using namespace mozilla::services;
/**
* Clears service cache, sets gXPCOMShuttingDown
*/
void
void
mozilla::services::Shutdown()
{
gXPCOMShuttingDown = true;

View File

@ -67,7 +67,7 @@ namespace internal {
class WindowsDllNopSpacePatcher
{
typedef unsigned char *byteptr_t;
typedef unsigned char* byteptr_t;
HMODULE mModule;
// Dumb array for remembering the addresses of functions we've patched.
@ -109,43 +109,45 @@ public:
}
}
void Init(const char *modulename)
void Init(const char* aModuleName)
{
mModule = LoadLibraryExA(modulename, nullptr, 0);
mModule = LoadLibraryExA(aModuleName, nullptr, 0);
if (!mModule) {
//printf("LoadLibraryEx for '%s' failed\n", modulename);
//printf("LoadLibraryEx for '%s' failed\n", aModuleName);
return;
}
}
#if defined(_M_IX86)
bool AddHook(const char *pname, intptr_t hookDest, void **origFunc)
bool AddHook(const char* aName, intptr_t aHookDest, void** aOrigFunc)
{
if (!mModule)
if (!mModule) {
return false;
}
if (mPatchedFnsLen == maxPatchedFns) {
// printf ("No space for hook in mPatchedFns.\n");
return false;
}
byteptr_t fn = reinterpret_cast<byteptr_t>(GetProcAddress(mModule, pname));
byteptr_t fn = reinterpret_cast<byteptr_t>(GetProcAddress(mModule, aName));
if (!fn) {
//printf ("GetProcAddress failed\n");
return false;
}
// Ensure we can read and write starting at fn - 5 (for the long jmp we're
// going to write) and ending at fn + 2 (for the short jmp up to the long
// jmp).
DWORD op;
if (!VirtualProtectEx(GetCurrentProcess(), fn - 5, 7, PAGE_EXECUTE_READWRITE, &op)) {
if (!VirtualProtectEx(GetCurrentProcess(), fn - 5, 7,
PAGE_EXECUTE_READWRITE, &op)) {
//printf ("VirtualProtectEx failed! %d\n", GetLastError());
return false;
}
bool rv = WriteHook(fn, hookDest, origFunc);
bool rv = WriteHook(fn, aHookDest, aOrigFunc);
// Re-protect, and we're done.
VirtualProtectEx(GetCurrentProcess(), fn - 5, 7, op, &op);
@ -157,17 +159,18 @@ public:
return rv;
}
bool WriteHook(byteptr_t fn, intptr_t hookDest, void **origFunc)
bool WriteHook(byteptr_t aFn, intptr_t aHookDest, void** aOrigFunc)
{
// Check that the 5 bytes before fn are NOP's or INT 3's,
// and that the 2 bytes after fn are mov(edi, edi).
// Check that the 5 bytes before aFn are NOP's or INT 3's,
// and that the 2 bytes after aFn are mov(edi, edi).
//
// It's safe to read fn[-5] because we set it to PAGE_EXECUTE_READWRITE
// It's safe to read aFn[-5] because we set it to PAGE_EXECUTE_READWRITE
// before calling WriteHook.
for (int i = -5; i <= -1; i++) {
if (fn[i] != 0x90 && fn[i] != 0xcc) // nop or int 3
if (aFn[i] != 0x90 && aFn[i] != 0xcc) { // nop or int 3
return false;
}
}
// mov edi, edi. Yes, there are two ways to encode the same thing:
@ -177,20 +180,20 @@ public:
//
// where "r" is register and "r/m" is register or memory. Windows seems to
// use 8bff; I include 89ff out of paranoia.
if ((fn[0] != 0x8b && fn[0] != 0x89) || fn[1] != 0xff) {
if ((aFn[0] != 0x8b && aFn[0] != 0x89) || aFn[1] != 0xff) {
return false;
}
// Write a long jump into the space above the function.
fn[-5] = 0xe9; // jmp
*((intptr_t*)(fn - 4)) = hookDest - (uintptr_t)(fn); // target displacement
aFn[-5] = 0xe9; // jmp
*((intptr_t*)(aFn - 4)) = aHookDest - (uintptr_t)(aFn); // target displacement
// Set origFunc here, because after this point, hookDest might be called,
// and hookDest might use the origFunc pointer.
*origFunc = fn + 2;
// Set aOrigFunc here, because after this point, aHookDest might be called,
// and aHookDest might use the aOrigFunc pointer.
*aOrigFunc = aFn + 2;
// Short jump up into our long jump.
*((uint16_t*)(fn)) = 0xf9eb; // jmp $-5
*((uint16_t*)(aFn)) = 0xf9eb; // jmp $-5
// I think this routine is safe without this, but it can't hurt.
FlushInstructionCache(GetCurrentProcess(),
@ -200,7 +203,7 @@ public:
return true;
}
#else
bool AddHook(const char *pname, intptr_t hookDest, void **origFunc)
bool AddHook(const char* aName, intptr_t aHookDest, void** aOrigFunc)
{
// Not implemented except on x86-32.
return false;
@ -210,9 +213,9 @@ public:
class WindowsDllDetourPatcher
{
typedef unsigned char *byteptr_t;
typedef unsigned char* byteptr_t;
public:
WindowsDllDetourPatcher()
WindowsDllDetourPatcher()
: mModule(0), mHookPage(0), mMaxHooks(0), mCurHooks(0)
{
}
@ -229,20 +232,22 @@ public:
#else
#error "Unknown processor type"
#endif
byteptr_t origBytes = *((byteptr_t *)p);
byteptr_t origBytes = *((byteptr_t*)p);
// ensure we can modify the original code
DWORD op;
if (!VirtualProtectEx(GetCurrentProcess(), origBytes, nBytes, PAGE_EXECUTE_READWRITE, &op)) {
if (!VirtualProtectEx(GetCurrentProcess(), origBytes, nBytes,
PAGE_EXECUTE_READWRITE, &op)) {
//printf ("VirtualProtectEx failed! %d\n", GetLastError());
continue;
}
// Remove the hook by making the original function jump directly
// in the trampoline.
intptr_t dest = (intptr_t)(p + sizeof(void *));
intptr_t dest = (intptr_t)(p + sizeof(void*));
#if defined(_M_IX86)
*((intptr_t*)(origBytes+1)) = dest - (intptr_t)(origBytes+5); // target displacement
*((intptr_t*)(origBytes + 1)) =
dest - (intptr_t)(origBytes + 5); // target displacement
#elif defined(_M_X64)
*((intptr_t*)(origBytes+2)) = dest;
*((intptr_t*)(origBytes + 2)) = dest;
#else
#error "Unknown processor type"
#endif
@ -251,63 +256,64 @@ public:
}
}
void Init(const char *modulename, int nhooks = 0)
void Init(const char* aModuleName, int aNumHooks = 0)
{
if (mModule)
if (mModule) {
return;
}
mModule = LoadLibraryExA(modulename, nullptr, 0);
mModule = LoadLibraryExA(aModuleName, nullptr, 0);
if (!mModule) {
//printf("LoadLibraryEx for '%s' failed\n", modulename);
//printf("LoadLibraryEx for '%s' failed\n", aModuleName);
return;
}
int hooksPerPage = 4096 / kHookSize;
if (nhooks == 0)
nhooks = hooksPerPage;
if (aNumHooks == 0) {
aNumHooks = hooksPerPage;
}
mMaxHooks = nhooks + (hooksPerPage % nhooks);
mHookPage = (byteptr_t) VirtualAllocEx(GetCurrentProcess(), nullptr,
mMaxHooks * kHookSize,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
mMaxHooks = aNumHooks + (hooksPerPage % aNumHooks);
mHookPage = (byteptr_t)VirtualAllocEx(GetCurrentProcess(), nullptr,
mMaxHooks * kHookSize,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (!mHookPage) {
mModule = 0;
return;
}
}
bool Initialized()
{
return !!mModule;
}
bool Initialized() { return !!mModule; }
void LockHooks()
{
if (!mModule)
if (!mModule) {
return;
}
DWORD op;
VirtualProtectEx(GetCurrentProcess(), mHookPage, mMaxHooks * kHookSize, PAGE_EXECUTE_READ, &op);
VirtualProtectEx(GetCurrentProcess(), mHookPage, mMaxHooks * kHookSize,
PAGE_EXECUTE_READ, &op);
mModule = 0;
}
bool AddHook(const char *pname, intptr_t hookDest, void **origFunc)
bool AddHook(const char* aName, intptr_t aHookDest, void** aOrigFunc)
{
if (!mModule)
if (!mModule) {
return false;
}
void *pAddr = (void *) GetProcAddress(mModule, pname);
void* pAddr = (void*)GetProcAddress(mModule, aName);
if (!pAddr) {
//printf ("GetProcAddress failed\n");
return false;
}
CreateTrampoline(pAddr, hookDest, origFunc);
if (!*origFunc) {
CreateTrampoline(pAddr, aHookDest, aOrigFunc);
if (!*aOrigFunc) {
//printf ("CreateTrampoline failed\n");
return false;
}
@ -324,17 +330,16 @@ protected:
int mMaxHooks;
int mCurHooks;
void CreateTrampoline(void *origFunction,
intptr_t dest,
void **outTramp)
void CreateTrampoline(void* aOrigFunction, intptr_t aDest, void** aOutTramp)
{
*outTramp = nullptr;
*aOutTramp = nullptr;
byteptr_t tramp = FindTrampolineSpace();
if (!tramp)
if (!tramp) {
return;
}
byteptr_t origBytes = (byteptr_t) origFunction;
byteptr_t origBytes = (byteptr_t)aOrigFunction;
int nBytes = 0;
int pJmp32 = -1;
@ -348,11 +353,10 @@ protected:
// need to rewrite the displacement argument.
if (origBytes[nBytes] >= 0x88 && origBytes[nBytes] <= 0x8B) {
// various MOVs
unsigned char b = origBytes[nBytes+1];
unsigned char b = origBytes[nBytes + 1];
if (((b & 0xc0) == 0xc0) ||
(((b & 0xc0) == 0x00) &&
((b & 0x07) != 0x04) && ((b & 0x07) != 0x05)))
{
((b & 0x07) != 0x04) && ((b & 0x07) != 0x05))) {
// REG=r, R/M=r or REG=r, R/M=[r]
nBytes += 2;
} else if ((b & 0xc0) == 0x40) {
@ -372,7 +376,7 @@ protected:
nBytes += 5;
} else if (origBytes[nBytes] == 0x83) {
// ADD|ODR|ADC|SBB|AND|SUB|XOR|CMP r/m, imm8
unsigned char b = origBytes[nBytes+1];
unsigned char b = origBytes[nBytes + 1];
if ((b & 0xc0) == 0xc0) {
// ADD|ODR|ADC|SBB|AND|SUB|XOR|CMP r, imm8
nBytes += 3;
@ -403,13 +407,14 @@ protected:
while (nBytes < 13) {
// if found JMP 32bit offset, next bytes must be NOP
// if found JMP 32bit offset, next bytes must be NOP
if (pJmp32 >= 0) {
if (origBytes[nBytes++] != 0x90)
if (origBytes[nBytes++] != 0x90) {
return;
}
continue;
}
}
if (origBytes[nBytes] == 0x0f) {
nBytes++;
if (origBytes[nBytes] == 0x1f) {
@ -454,30 +459,32 @@ protected:
// REX.W | REX.WR
nBytes++;
if (origBytes[nBytes] == 0x81 && (origBytes[nBytes+1] & 0xf8) == 0xe8) {
if (origBytes[nBytes] == 0x81 &&
(origBytes[nBytes + 1] & 0xf8) == 0xe8) {
// sub r, dword
nBytes += 6;
} else if (origBytes[nBytes] == 0x83 &&
(origBytes[nBytes+1] & 0xf8) == 0xe8) {
(origBytes[nBytes + 1] & 0xf8) == 0xe8) {
// sub r, byte
nBytes += 3;
} else if (origBytes[nBytes] == 0x83 &&
(origBytes[nBytes+1] & 0xf8) == 0x60) {
(origBytes[nBytes + 1] & 0xf8) == 0x60) {
// and [r+d], imm8
nBytes += 5;
} else if ((origBytes[nBytes] & 0xfd) == 0x89) {
// MOV r/m64, r64 | MOV r64, r/m64
if ((origBytes[nBytes+1] & 0xc0) == 0x40) {
if ((origBytes[nBytes+1] & 0x7) == 0x04) {
if ((origBytes[nBytes + 1] & 0xc0) == 0x40) {
if ((origBytes[nBytes + 1] & 0x7) == 0x04) {
// R/M=[SIB+disp8], REG=r64
nBytes += 4;
} else {
// R/M=[r64+disp8], REG=r64
nBytes += 3;
}
} else if (((origBytes[nBytes+1] & 0xc0) == 0xc0) ||
(((origBytes[nBytes+1] & 0xc0) == 0x00) &&
((origBytes[nBytes+1] & 0x07) != 0x04) && ((origBytes[nBytes+1] & 0x07) != 0x05))) {
} else if (((origBytes[nBytes + 1] & 0xc0) == 0xc0) ||
(((origBytes[nBytes + 1] & 0xc0) == 0x00) &&
((origBytes[nBytes + 1] & 0x07) != 0x04) &&
((origBytes[nBytes + 1] & 0x07) != 0x05))) {
// REG=r64, R/M=r64 or REG=r64, R/M=[r64]
nBytes += 2;
} else {
@ -496,11 +503,13 @@ protected:
} else if (origBytes[nBytes] == 0xff) {
pJmp32 = nBytes - 1;
// JMP /4
if ((origBytes[nBytes+1] & 0xc0) == 0x0 &&
(origBytes[nBytes+1] & 0x07) == 0x5) {
if ((origBytes[nBytes + 1] & 0xc0) == 0x0 &&
(origBytes[nBytes + 1] & 0x07) == 0x5) {
// [rip+disp32]
// convert JMP 32bit offset to JMP 64bit direct
directJmpAddr = (byteptr_t)*((uint64_t*)(origBytes + nBytes + 6 + (*((int32_t*)(origBytes + nBytes + 2)))));
directJmpAddr =
(byteptr_t)*((uint64_t*)(origBytes + nBytes + 6 +
(*((int32_t*)(origBytes + nBytes + 2)))));
nBytes += 6;
} else {
// not support yet!
@ -551,10 +560,10 @@ protected:
// We keep the address of the original function in the first bytes of
// the trampoline buffer
*((void **)tramp) = origFunction;
tramp += sizeof(void *);
*((void**)tramp) = aOrigFunction;
tramp += sizeof(void*);
memcpy(tramp, origFunction, nBytes);
memcpy(tramp, aOrigFunction, nBytes);
// OrigFunction+N, the target of the trampoline
byteptr_t trampDest = origBytes + nBytes;
@ -564,42 +573,44 @@ protected:
// Jump directly to the original target of the jump instead of jumping to the
// original function.
// Adjust jump target displacement to jump location in the trampoline.
*((intptr_t*)(tramp+pJmp32+1)) += origBytes - tramp;
*((intptr_t*)(tramp + pJmp32 + 1)) += origBytes - tramp;
} else {
tramp[nBytes] = 0xE9; // jmp
*((intptr_t*)(tramp+nBytes+1)) = (intptr_t)trampDest - (intptr_t)(tramp+nBytes+5); // target displacement
*((intptr_t*)(tramp + nBytes + 1)) =
(intptr_t)trampDest - (intptr_t)(tramp + nBytes + 5); // target displacement
}
#elif defined(_M_X64)
// If JMP32 opcode found, we don't insert to trampoline jump
// If JMP32 opcode found, we don't insert to trampoline jump
if (pJmp32 >= 0) {
// mov r11, address
tramp[pJmp32] = 0x49;
tramp[pJmp32+1] = 0xbb;
*((intptr_t*)(tramp+pJmp32+2)) = (intptr_t)directJmpAddr;
tramp[pJmp32 + 1] = 0xbb;
*((intptr_t*)(tramp + pJmp32 + 2)) = (intptr_t)directJmpAddr;
// jmp r11
tramp[pJmp32+10] = 0x41;
tramp[pJmp32+11] = 0xff;
tramp[pJmp32+12] = 0xe3;
tramp[pJmp32 + 10] = 0x41;
tramp[pJmp32 + 11] = 0xff;
tramp[pJmp32 + 12] = 0xe3;
} else {
// mov r11, address
tramp[nBytes] = 0x49;
tramp[nBytes+1] = 0xbb;
*((intptr_t*)(tramp+nBytes+2)) = (intptr_t)trampDest;
tramp[nBytes + 1] = 0xbb;
*((intptr_t*)(tramp + nBytes + 2)) = (intptr_t)trampDest;
// jmp r11
tramp[nBytes+10] = 0x41;
tramp[nBytes+11] = 0xff;
tramp[nBytes+12] = 0xe3;
tramp[nBytes + 10] = 0x41;
tramp[nBytes + 11] = 0xff;
tramp[nBytes + 12] = 0xe3;
}
#endif
// The trampoline is now valid.
*outTramp = tramp;
*aOutTramp = tramp;
// ensure we can modify the original code
DWORD op;
if (!VirtualProtectEx(GetCurrentProcess(), origFunction, nBytes, PAGE_EXECUTE_READWRITE, &op)) {
if (!VirtualProtectEx(GetCurrentProcess(), aOrigFunction, nBytes,
PAGE_EXECUTE_READWRITE, &op)) {
//printf ("VirtualProtectEx failed! %d\n", GetLastError());
return;
}
@ -607,13 +618,14 @@ protected:
#if defined(_M_IX86)
// now modify the original bytes
origBytes[0] = 0xE9; // jmp
*((intptr_t*)(origBytes+1)) = dest - (intptr_t)(origBytes+5); // target displacement
*((intptr_t*)(origBytes + 1)) =
aDest - (intptr_t)(origBytes + 5); // target displacement
#elif defined(_M_X64)
// mov r11, address
origBytes[0] = 0x49;
origBytes[1] = 0xbb;
*((intptr_t*)(origBytes+2)) = dest;
*((intptr_t*)(origBytes + 2)) = aDest;
// jmp r11
origBytes[10] = 0x41;
@ -622,15 +634,16 @@ protected:
#endif
// restore protection; if this fails we can't really do anything about it
VirtualProtectEx(GetCurrentProcess(), origFunction, nBytes, op, &op);
VirtualProtectEx(GetCurrentProcess(), aOrigFunction, nBytes, op, &op);
}
byteptr_t FindTrampolineSpace()
{
if (mCurHooks >= mMaxHooks)
if (mCurHooks >= mMaxHooks) {
return 0;
}
byteptr_t p = mHookPage + mCurHooks*kHookSize;
byteptr_t p = mHookPage + mCurHooks * kHookSize;
mCurHooks++;
@ -645,7 +658,7 @@ class WindowsDllInterceptor
internal::WindowsDllNopSpacePatcher mNopSpacePatcher;
internal::WindowsDllDetourPatcher mDetourPatcher;
const char *mModuleName;
const char* mModuleName;
int mNHooks;
public:
@ -654,15 +667,15 @@ public:
, mNHooks(0)
{}
void Init(const char *moduleName, int nhooks = 0)
void Init(const char* aModuleName, int aNumHooks = 0)
{
if (mModuleName) {
return;
}
mModuleName = moduleName;
mNHooks = nhooks;
mNopSpacePatcher.Init(moduleName);
mModuleName = aModuleName;
mNHooks = aNumHooks;
mNopSpacePatcher.Init(aModuleName);
// Lazily initialize mDetourPatcher, since it allocates memory and we might
// not need it.
@ -670,11 +683,12 @@ public:
void LockHooks()
{
if (mDetourPatcher.Initialized())
if (mDetourPatcher.Initialized()) {
mDetourPatcher.LockHooks();
}
}
bool AddHook(const char *pname, intptr_t hookDest, void **origFunc)
bool AddHook(const char* aName, intptr_t aHookDest, void** aOrigFunc)
{
// Use a nop space patch if possible, otherwise fall back to a detour.
// This should be the preferred method for adding hooks.
@ -683,14 +697,14 @@ public:
return false;
}
if (mNopSpacePatcher.AddHook(pname, hookDest, origFunc)) {
if (mNopSpacePatcher.AddHook(aName, aHookDest, aOrigFunc)) {
return true;
}
return AddDetour(pname, hookDest, origFunc);
return AddDetour(aName, aHookDest, aOrigFunc);
}
bool AddDetour(const char *pname, intptr_t hookDest, void **origFunc)
bool AddDetour(const char* aName, intptr_t aHookDest, void** aOrigFunc)
{
// Generally, code should not call this method directly. Use AddHook unless
// there is a specific need to avoid nop space patches.
@ -703,7 +717,7 @@ public:
mDetourPatcher.Init(mModuleName, mNHooks);
}
return mDetourPatcher.AddHook(pname, hookDest, origFunc);
return mDetourPatcher.AddHook(aName, aHookDest, aOrigFunc);
}
};

View File

@ -41,22 +41,22 @@ struct Module;
* Initialises XPCOM. You must call one of the NS_InitXPCOM methods
* before proceeding to use xpcom. The one exception is that you may
* call NS_NewLocalFile to create a nsIFile.
*
* @note Use <CODE>NS_NewLocalFile</CODE> or <CODE>NS_NewNativeLocalFile</CODE>
*
* @note Use <CODE>NS_NewLocalFile</CODE> or <CODE>NS_NewNativeLocalFile</CODE>
* to create the file object you supply as the bin directory path in this
* call. The function may be safely called before the rest of XPCOM or
* call. The function may be safely called before the rest of XPCOM or
* embedding has been initialised.
*
* @param result The service manager. You may pass null.
* @param aResult The service manager. You may pass null.
*
* @param binDirectory The directory containing the component
* @param aBinDirectory The directory containing the component
* registry and runtime libraries;
* or use <CODE>nullptr</CODE> to use the working
* directory.
*
* @param appFileLocationProvider The object to be used by Gecko that specifies
* to Gecko where to find profiles, the component
* registry preferences and so on; or use
* @param aAppFileLocationProvider The object to be used by Gecko that
* specifies to Gecko where to find profiles, the
* component registry preferences and so on; or use
* <CODE>nullptr</CODE> for the default behaviour.
*
* @see NS_NewLocalFile
@ -70,90 +70,80 @@ struct Module;
* initialisation.
*/
XPCOM_API(nsresult)
NS_InitXPCOM2(nsIServiceManager* *result,
nsIFile* binDirectory,
nsIDirectoryServiceProvider* appFileLocationProvider);
NS_InitXPCOM2(nsIServiceManager** aResult,
nsIFile* aBinDirectory,
nsIDirectoryServiceProvider* aAppFileLocationProvider);
/**
* Shutdown XPCOM. You must call this method after you are finished
* using xpcom.
* using xpcom.
*
* @param servMgr The service manager which was returned by NS_InitXPCOM.
* @param aServMgr The service manager which was returned by NS_InitXPCOM.
* This will release servMgr. You may pass null.
*
* @return NS_OK for success;
* other error codes indicate a failure during initialisation.
*
*/
XPCOM_API(nsresult)
NS_ShutdownXPCOM(nsIServiceManager* servMgr);
XPCOM_API(nsresult) NS_ShutdownXPCOM(nsIServiceManager* aServMgr);
/**
* Public Method to access to the service manager.
*
* @param result Interface pointer to the service manager
*
* @param aResult Interface pointer to the service manager
*
* @return NS_OK for success;
* other error codes indicate a failure during initialisation.
*
*/
XPCOM_API(nsresult)
NS_GetServiceManager(nsIServiceManager* *result);
XPCOM_API(nsresult) NS_GetServiceManager(nsIServiceManager** aResult);
/**
* Public Method to access to the component manager.
*
* @param result Interface pointer to the service
*
* @param aResult Interface pointer to the service
*
* @return NS_OK for success;
* other error codes indicate a failure during initialisation.
*
*/
XPCOM_API(nsresult)
NS_GetComponentManager(nsIComponentManager* *result);
XPCOM_API(nsresult) NS_GetComponentManager(nsIComponentManager** aResult);
/**
* Public Method to access to the component registration manager.
*
* @param result Interface pointer to the service
* @param aResult Interface pointer to the service
*
* @return NS_OK for success;
* other error codes indicate a failure during initialisation.
*
*/
XPCOM_API(nsresult)
NS_GetComponentRegistrar(nsIComponentRegistrar* *result);
XPCOM_API(nsresult) NS_GetComponentRegistrar(nsIComponentRegistrar** aResult);
/**
* Public Method to access to the memory manager. See nsIMemory
*
* @param result Interface pointer to the memory manager
*
* @param aResult Interface pointer to the memory manager
*
* @return NS_OK for success;
* other error codes indicate a failure during initialisation.
*
*/
XPCOM_API(nsresult)
NS_GetMemoryManager(nsIMemory* *result);
XPCOM_API(nsresult) NS_GetMemoryManager(nsIMemory** aResult);
/**
* Public Method to create an instance of a nsIFile. This function
* may be called prior to NS_InitXPCOM.
*
* @param path
* A string which specifies a full file path to a
*
* @param aPath
* A string which specifies a full file path to a
* location. Relative paths will be treated as an
* error (NS_ERROR_FILE_UNRECOGNIZED_PATH).
* |NS_NewNativeLocalFile|'s path must be in the
* error (NS_ERROR_FILE_UNRECOGNIZED_PATH).
* |NS_NewNativeLocalFile|'s path must be in the
* filesystem charset.
* @param followLinks
* @param aFollowLinks
* This attribute will determine if the nsLocalFile will auto
* resolve symbolic links. By default, this value will be false
* on all non unix systems. On unix, this attribute is effectively
* a noop.
* @param result Interface pointer to a new instance of an nsIFile
* a noop.
* @param aResult Interface pointer to a new instance of an nsIFile
*
* @return NS_OK for success;
* other error codes indicate a failure.
@ -161,15 +151,13 @@ NS_GetMemoryManager(nsIMemory* *result);
#ifdef __cplusplus
XPCOM_API(nsresult)
NS_NewLocalFile(const nsAString &path,
bool followLinks,
nsIFile* *result);
XPCOM_API(nsresult) NS_NewLocalFile(const nsAString& aPath,
bool aFollowLinks,
nsIFile** aResult);
XPCOM_API(nsresult)
NS_NewNativeLocalFile(const nsACString &path,
bool followLinks,
nsIFile* *result);
XPCOM_API(nsresult) NS_NewNativeLocalFile(const nsACString& aPath,
bool aFollowLinks,
nsIFile** aResult);
#endif
@ -177,57 +165,55 @@ NS_NewNativeLocalFile(const nsACString &path,
* Allocates a block of memory of a particular size. If the memory cannot
* be allocated (because of an out-of-memory condition), the process aborts.
*
* @param size The size of the block to allocate
* @param aSize The size of the block to allocate
* @result The block of memory
* @note This function is thread-safe.
*/
XPCOM_API(void*)
NS_Alloc(size_t size);
XPCOM_API(void*) NS_Alloc(size_t aSize);
/**
* Reallocates a block of memory to a new size.
*
* @param ptr The block of memory to reallocate. This block must originally
* @param aPtr The block of memory to reallocate. This block must originally
have been allocated by NS_Alloc or NS_Realloc
* @param size The new size. If 0, frees the block like NS_Free
* @param aSize The new size. If 0, frees the block like NS_Free
* @result The reallocated block of memory
* @note This function is thread-safe.
*
* If ptr is null, this function behaves like NS_Alloc.
* If s is the size of the block to which ptr points, the first min(s, size)
* bytes of ptr's block are copied to the new block. If the allocation
* succeeds, ptr is freed and a pointer to the new block is returned. If the
* If aPtr is null, this function behaves like NS_Alloc.
* If s is the size of the block to which aPtr points, the first min(s, size)
* bytes of aPtr's block are copied to the new block. If the allocation
* succeeds, aPtr is freed and a pointer to the new block is returned. If the
* allocation fails, the process aborts.
*/
XPCOM_API(void*)
NS_Realloc(void* ptr, size_t size);
XPCOM_API(void*) NS_Realloc(void* aPtr, size_t aSize);
/**
* Frees a block of memory. Null is a permissible value, in which case no
* action is taken.
*
* @param ptr The block of memory to free. This block must originally have
* @param aPtr The block of memory to free. This block must originally have
* been allocated by NS_Alloc or NS_Realloc
* @note This function is thread-safe.
*/
XPCOM_API(void)
NS_Free(void* ptr);
XPCOM_API(void) NS_Free(void* aPtr);
/**
* Support for warnings, assertions, and debugging breaks.
*/
enum {
NS_DEBUG_WARNING = 0,
NS_DEBUG_ASSERTION = 1,
NS_DEBUG_BREAK = 2,
NS_DEBUG_ABORT = 3
enum
{
NS_DEBUG_WARNING = 0,
NS_DEBUG_ASSERTION = 1,
NS_DEBUG_BREAK = 2,
NS_DEBUG_ABORT = 3
};
/**
* Print a runtime assertion. This function is available in both debug and
* release builds.
*
*
* @note Based on the value of aSeverity and the XPCOM_DEBUG_BREAK
* environment variable, this function may cause the application to
* print the warning, print a stacktrace, break into a debugger, or abort
@ -239,10 +225,9 @@ enum {
* @param aFile The source file containing the assertion (may be null)
* @param aLine The source file line number (-1 indicates no line number)
*/
XPCOM_API(void)
NS_DebugBreak(uint32_t aSeverity,
const char *aStr, const char *aExpr,
const char *aFile, int32_t aLine);
XPCOM_API(void) NS_DebugBreak(uint32_t aSeverity,
const char* aStr, const char* aExpr,
const char* aFile, int32_t aLine);
/**
* Perform a stack-walk to a debugging log under various
@ -260,11 +245,9 @@ NS_DebugBreak(uint32_t aSeverity,
* printing of logging statistics. They should always be used as a
* matched pair.
*/
XPCOM_API(void)
NS_LogInit();
XPCOM_API(void) NS_LogInit();
XPCOM_API(void)
NS_LogTerm();
XPCOM_API(void) NS_LogTerm();
/**
* Log construction and destruction of objects. Processing tools can use the
@ -276,11 +259,11 @@ NS_LogTerm();
* @param aInstanceSize The size of the type
*/
XPCOM_API(void)
NS_LogCtor(void *aPtr, const char *aTypeName, uint32_t aInstanceSize);
XPCOM_API(void) NS_LogCtor(void* aPtr, const char* aTypeName,
uint32_t aInstanceSize);
XPCOM_API(void)
NS_LogDtor(void *aPtr, const char *aTypeName, uint32_t aInstanceSize);
XPCOM_API(void) NS_LogDtor(void* aPtr, const char* aTypeName,
uint32_t aInstanceSize);
/**
* Log a stacktrace when an XPCOM object's refcount is incremented or
@ -292,12 +275,11 @@ NS_LogDtor(void *aPtr, const char *aTypeName, uint32_t aInstanceSize);
* @param aTypeName The class name of the type
* @param aInstanceSize The size of the type
*/
XPCOM_API(void)
NS_LogAddRef(void *aPtr, nsrefcnt aNewRefCnt,
const char *aTypeName, uint32_t aInstanceSize);
XPCOM_API(void) NS_LogAddRef(void* aPtr, nsrefcnt aNewRefCnt,
const char* aTypeName, uint32_t aInstanceSize);
XPCOM_API(void)
NS_LogRelease(void *aPtr, nsrefcnt aNewRefCnt, const char *aTypeName);
XPCOM_API(void) NS_LogRelease(void* aPtr, nsrefcnt aNewRefCnt,
const char* aTypeName);
/**
* Log reference counting performed by COMPtrs. Processing tools can
@ -309,11 +291,9 @@ NS_LogRelease(void *aPtr, nsrefcnt aNewRefCnt, const char *aTypeName);
* @param aObject the object being referenced by the COMPtr
*/
XPCOM_API(void)
NS_LogCOMPtrAddRef(void *aCOMPtr, nsISupports *aObject);
XPCOM_API(void) NS_LogCOMPtrAddRef(void* aCOMPtr, nsISupports* aObject);
XPCOM_API(void)
NS_LogCOMPtrRelease(void *aCOMPtr, nsISupports *aObject);
XPCOM_API(void) NS_LogCOMPtrRelease(void* aCOMPtr, nsISupports* aObject);
/**
* The XPCOM cycle collector analyzes and breaks reference cycles between
@ -326,10 +306,10 @@ NS_LogCOMPtrRelease(void *aCOMPtr, nsISupports *aObject);
class nsCycleCollectionParticipant;
class nsCycleCollectingAutoRefCnt;
XPCOM_API(void)
NS_CycleCollectorSuspect3(void *n, nsCycleCollectionParticipant *p,
nsCycleCollectingAutoRefCnt *aRefCnt,
bool* aShouldDelete);
XPCOM_API(void) NS_CycleCollectorSuspect3(void* aPtr,
nsCycleCollectionParticipant* aCp,
nsCycleCollectingAutoRefCnt* aRefCnt,
bool* aShouldDelete);
#endif
@ -408,7 +388,6 @@ NS_CycleCollectorSuspect3(void *n, nsCycleCollectionParticipant *p,
*/
#define NS_XPCOM_CATEGORY_CLEARED_OBSERVER_ID "xpcom-category-cleared"
XPCOM_API(nsresult)
NS_GetDebug(nsIDebug* *result);
XPCOM_API(nsresult) NS_GetDebug(nsIDebug** aResult);
#endif

View File

@ -8,7 +8,7 @@
/**
* XPCOM Directory Service Contract ID
* The directory service provides ways to obtain file system locations. The
* The directory service provides ways to obtain file system locations. The
* directory service is a singleton.
*
* This contract supports the nsIDirectoryService and the nsIProperties
@ -19,11 +19,11 @@
/**
* XPCOM File
* The file abstraction provides ways to obtain and access files and
* directories located on the local system.
* The file abstraction provides ways to obtain and access files and
* directories located on the local system.
*
* This contract supports the nsIFile interface.
* This contract may also support platform specific interfaces such as
* This contract may also support platform specific interfaces such as
* nsILocalFileMac on platforms where additional interfaces are required.
*
*/
@ -31,7 +31,7 @@
/**
* XPCOM Category Manager Contract ID
* The contract supports the nsICategoryManager interface. The
* The contract supports the nsICategoryManager interface. The
* category manager is a singleton.
* The "enumerateCategory" method of nsICategoryManager will return an object
* that implements nsIUTF8StringEnumerator. In addition, the enumerator will
@ -91,8 +91,8 @@
#define NS_MESSAGE_LOOP_CONTRACTID "@mozilla.org/message-loop;1"
/**
* The following are the CIDs and Contract IDs of the nsISupports wrappers for
* primative types.
* The following are the CIDs and Contract IDs of the nsISupports wrappers for
* primative types.
*/
#define NS_SUPPORTS_ID_CID \
{ 0xacf8dc40, 0x4a25, 0x11d3, \

View File

@ -30,160 +30,185 @@ class nsPurpleBufferEntry;
#define NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID "xpcom-shutdown-loaders"
// PUBLIC
typedef nsresult (* InitFunc)(nsIServiceManager* *result, nsIFile* binDirectory, nsIDirectoryServiceProvider* appFileLocationProvider);
typedef nsresult (* ShutdownFunc)(nsIServiceManager* servMgr);
typedef nsresult (* GetServiceManagerFunc)(nsIServiceManager* *result);
typedef nsresult (* GetComponentManagerFunc)(nsIComponentManager* *result);
typedef nsresult (* GetComponentRegistrarFunc)(nsIComponentRegistrar* *result);
typedef nsresult (* GetMemoryManagerFunc)(nsIMemory* *result);
typedef nsresult (* NewLocalFileFunc)(const nsAString &path, bool followLinks, nsIFile* *result);
typedef nsresult (* NewNativeLocalFileFunc)(const nsACString &path, bool followLinks, nsIFile* *result);
typedef nsresult (*InitFunc)(nsIServiceManager** aResult,
nsIFile* aBinDirectory,
nsIDirectoryServiceProvider* aAppFileLocationProvider);
typedef nsresult (*ShutdownFunc)(nsIServiceManager* aServMgr);
typedef nsresult (*GetServiceManagerFunc)(nsIServiceManager** aResult);
typedef nsresult (*GetComponentManagerFunc)(nsIComponentManager** aResult);
typedef nsresult (*GetComponentRegistrarFunc)(nsIComponentRegistrar** aResult);
typedef nsresult (*GetMemoryManagerFunc)(nsIMemory** aResult);
typedef nsresult (*NewLocalFileFunc)(const nsAString& aPath,
bool aFollowLinks, nsIFile** aResult);
typedef nsresult (*NewNativeLocalFileFunc)(const nsACString& aPath,
bool aFollowLinks,
nsIFile** aResult);
typedef nsresult (* GetDebugFunc)(nsIDebug* *result);
typedef nsresult (*GetDebugFunc)(nsIDebug** aResult);
typedef nsresult (* StringContainerInitFunc)(nsStringContainer&);
typedef nsresult (* StringContainerInit2Func)(nsStringContainer&, const char16_t *, uint32_t, uint32_t);
typedef void (* StringContainerFinishFunc)(nsStringContainer&);
typedef uint32_t (* StringGetDataFunc)(const nsAString&, const char16_t**, bool*);
typedef uint32_t (* StringGetMutableDataFunc)(nsAString&, uint32_t, char16_t**);
typedef char16_t* (* StringCloneDataFunc)(const nsAString&);
typedef nsresult (* StringSetDataFunc)(nsAString&, const char16_t*, uint32_t);
typedef nsresult (* StringSetDataRangeFunc)(nsAString&, uint32_t, uint32_t, const char16_t*, uint32_t);
typedef nsresult (* StringCopyFunc)(nsAString &, const nsAString &);
typedef void (* StringSetIsVoidFunc)(nsAString &, const bool);
typedef bool (* StringGetIsVoidFunc)(const nsAString &);
typedef nsresult (*StringContainerInitFunc)(nsStringContainer&);
typedef nsresult (*StringContainerInit2Func)(nsStringContainer&,
const char16_t*,
uint32_t, uint32_t);
typedef void (*StringContainerFinishFunc)(nsStringContainer&);
typedef uint32_t (*StringGetDataFunc)(const nsAString&, const char16_t**,
bool*);
typedef uint32_t (*StringGetMutableDataFunc)(nsAString&, uint32_t,
char16_t**);
typedef char16_t* (*StringCloneDataFunc)(const nsAString&);
typedef nsresult (*StringSetDataFunc)(nsAString&, const char16_t*, uint32_t);
typedef nsresult (*StringSetDataRangeFunc)(nsAString&, uint32_t, uint32_t,
const char16_t*, uint32_t);
typedef nsresult (*StringCopyFunc)(nsAString&, const nsAString&);
typedef void (*StringSetIsVoidFunc)(nsAString&, const bool);
typedef bool (*StringGetIsVoidFunc)(const nsAString&);
typedef nsresult (* CStringContainerInitFunc)(nsCStringContainer&);
typedef nsresult (* CStringContainerInit2Func)(nsCStringContainer&, const char *, uint32_t, uint32_t);
typedef void (* CStringContainerFinishFunc)(nsCStringContainer&);
typedef uint32_t (* CStringGetDataFunc)(const nsACString&, const char**, bool*);
typedef uint32_t (* CStringGetMutableDataFunc)(nsACString&, uint32_t, char**);
typedef char* (* CStringCloneDataFunc)(const nsACString&);
typedef nsresult (* CStringSetDataFunc)(nsACString&, const char*, uint32_t);
typedef nsresult (* CStringSetDataRangeFunc)(nsACString&, uint32_t, uint32_t, const char*, uint32_t);
typedef nsresult (* CStringCopyFunc)(nsACString &, const nsACString &);
typedef void (* CStringSetIsVoidFunc)(nsACString &, const bool);
typedef bool (* CStringGetIsVoidFunc)(const nsACString &);
typedef nsresult (*CStringContainerInitFunc)(nsCStringContainer&);
typedef nsresult (*CStringContainerInit2Func)(nsCStringContainer&,
const char*,
uint32_t, uint32_t);
typedef void (*CStringContainerFinishFunc)(nsCStringContainer&);
typedef uint32_t (*CStringGetDataFunc)(const nsACString&, const char**,
bool*);
typedef uint32_t (*CStringGetMutableDataFunc)(nsACString&, uint32_t, char**);
typedef char* (*CStringCloneDataFunc)(const nsACString&);
typedef nsresult (*CStringSetDataFunc)(nsACString&, const char*, uint32_t);
typedef nsresult (*CStringSetDataRangeFunc)(nsACString&, uint32_t, uint32_t,
const char*, uint32_t);
typedef nsresult (*CStringCopyFunc)(nsACString&, const nsACString&);
typedef void (*CStringSetIsVoidFunc)(nsACString&, const bool);
typedef bool (*CStringGetIsVoidFunc)(const nsACString&);
typedef nsresult (* CStringToUTF16)(const nsACString &, nsCStringEncoding, nsAString &);
typedef nsresult (* UTF16ToCString)(const nsAString &, nsCStringEncoding, nsACString &);
typedef nsresult (*CStringToUTF16)(const nsACString&, nsCStringEncoding,
nsAString&);
typedef nsresult (*UTF16ToCString)(const nsAString&, nsCStringEncoding,
nsACString&);
typedef void* (* AllocFunc)(size_t size);
typedef void* (* ReallocFunc)(void* ptr, size_t size);
typedef void (* FreeFunc)(void* ptr);
typedef void* (*AllocFunc)(size_t aSize);
typedef void* (*ReallocFunc)(void* aPtr, size_t aSize);
typedef void (*FreeFunc)(void* aPtr);
typedef void (* DebugBreakFunc)(uint32_t aSeverity,
const char *aStr, const char *aExpr,
const char *aFile, int32_t aLine);
typedef void (*DebugBreakFunc)(uint32_t aSeverity,
const char* aStr, const char* aExpr,
const char* aFile, int32_t aLine);
typedef void (* xpcomVoidFunc)();
typedef void (* LogAddRefFunc)(void*, nsrefcnt, const char*, uint32_t);
typedef void (* LogReleaseFunc)(void*, nsrefcnt, const char*);
typedef void (* LogCtorFunc)(void*, const char*, uint32_t);
typedef void (* LogCOMPtrFunc)(void*, nsISupports*);
typedef void (*xpcomVoidFunc)();
typedef void (*LogAddRefFunc)(void*, nsrefcnt, const char*, uint32_t);
typedef void (*LogReleaseFunc)(void*, nsrefcnt, const char*);
typedef void (*LogCtorFunc)(void*, const char*, uint32_t);
typedef void (*LogCOMPtrFunc)(void*, nsISupports*);
typedef nsresult (* GetXPTCallStubFunc)(REFNSIID, nsIXPTCProxy*, nsISomeInterface**);
typedef void (* DestroyXPTCallStubFunc)(nsISomeInterface*);
typedef nsresult (* InvokeByIndexFunc)(nsISupports*, uint32_t, uint32_t, nsXPTCVariant*);
typedef bool (* CycleCollectorFunc)(nsISupports*);
typedef nsresult (*GetXPTCallStubFunc)(REFNSIID, nsIXPTCProxy*,
nsISomeInterface**);
typedef void (*DestroyXPTCallStubFunc)(nsISomeInterface*);
typedef nsresult (*InvokeByIndexFunc)(nsISupports*, uint32_t, uint32_t,
nsXPTCVariant*);
typedef bool (*CycleCollectorFunc)(nsISupports*);
typedef nsPurpleBufferEntry*
(* CycleCollectorSuspect2Func)(void*, nsCycleCollectionParticipant*);
typedef bool (* CycleCollectorForget2Func)(nsPurpleBufferEntry*);
typedef void (* CycleCollectorSuspect3Func)(void*, nsCycleCollectionParticipant*,nsCycleCollectingAutoRefCnt*,bool*);
(*CycleCollectorSuspect2Func)(void*,
nsCycleCollectionParticipant*);
typedef bool (*CycleCollectorForget2Func)(nsPurpleBufferEntry*);
typedef void (*CycleCollectorSuspect3Func)(void*,
nsCycleCollectionParticipant*,
nsCycleCollectingAutoRefCnt*,
bool*);
// PRIVATE AND DEPRECATED
typedef NS_CALLBACK(XPCOMExitRoutine)(void);
typedef nsresult (* RegisterXPCOMExitRoutineFunc)(XPCOMExitRoutine exitRoutine, uint32_t priority);
typedef nsresult (* UnregisterXPCOMExitRoutineFunc)(XPCOMExitRoutine exitRoutine);
typedef nsresult (*RegisterXPCOMExitRoutineFunc)(XPCOMExitRoutine aExitRoutine,
uint32_t aPriority);
typedef nsresult (*UnregisterXPCOMExitRoutineFunc)(XPCOMExitRoutine aExitRoutine);
typedef struct XPCOMFunctions{
uint32_t version;
uint32_t size;
typedef struct XPCOMFunctions
{
uint32_t version;
uint32_t size;
InitFunc init;
ShutdownFunc shutdown;
GetServiceManagerFunc getServiceManager;
GetComponentManagerFunc getComponentManager;
GetComponentRegistrarFunc getComponentRegistrar;
GetMemoryManagerFunc getMemoryManager;
NewLocalFileFunc newLocalFile;
NewNativeLocalFileFunc newNativeLocalFile;
InitFunc init;
ShutdownFunc shutdown;
GetServiceManagerFunc getServiceManager;
GetComponentManagerFunc getComponentManager;
GetComponentRegistrarFunc getComponentRegistrar;
GetMemoryManagerFunc getMemoryManager;
NewLocalFileFunc newLocalFile;
NewNativeLocalFileFunc newNativeLocalFile;
RegisterXPCOMExitRoutineFunc registerExitRoutine;
UnregisterXPCOMExitRoutineFunc unregisterExitRoutine;
RegisterXPCOMExitRoutineFunc registerExitRoutine;
UnregisterXPCOMExitRoutineFunc unregisterExitRoutine;
// Added for Mozilla 1.5
GetDebugFunc getDebug;
void* getTraceRefcnt;
// Added for Mozilla 1.5
GetDebugFunc getDebug;
void* getTraceRefcnt;
// Added for Mozilla 1.7
StringContainerInitFunc stringContainerInit;
StringContainerFinishFunc stringContainerFinish;
StringGetDataFunc stringGetData;
StringSetDataFunc stringSetData;
StringSetDataRangeFunc stringSetDataRange;
StringCopyFunc stringCopy;
CStringContainerInitFunc cstringContainerInit;
CStringContainerFinishFunc cstringContainerFinish;
CStringGetDataFunc cstringGetData;
CStringSetDataFunc cstringSetData;
CStringSetDataRangeFunc cstringSetDataRange;
CStringCopyFunc cstringCopy;
CStringToUTF16 cstringToUTF16;
UTF16ToCString utf16ToCString;
StringCloneDataFunc stringCloneData;
CStringCloneDataFunc cstringCloneData;
// Added for Mozilla 1.7
StringContainerInitFunc stringContainerInit;
StringContainerFinishFunc stringContainerFinish;
StringGetDataFunc stringGetData;
StringSetDataFunc stringSetData;
StringSetDataRangeFunc stringSetDataRange;
StringCopyFunc stringCopy;
CStringContainerInitFunc cstringContainerInit;
CStringContainerFinishFunc cstringContainerFinish;
CStringGetDataFunc cstringGetData;
CStringSetDataFunc cstringSetData;
CStringSetDataRangeFunc cstringSetDataRange;
CStringCopyFunc cstringCopy;
CStringToUTF16 cstringToUTF16;
UTF16ToCString utf16ToCString;
StringCloneDataFunc stringCloneData;
CStringCloneDataFunc cstringCloneData;
// Added for Mozilla 1.8
AllocFunc allocFunc;
ReallocFunc reallocFunc;
FreeFunc freeFunc;
StringContainerInit2Func stringContainerInit2;
CStringContainerInit2Func cstringContainerInit2;
StringGetMutableDataFunc stringGetMutableData;
CStringGetMutableDataFunc cstringGetMutableData;
void* init3; // obsolete
// Added for Mozilla 1.8
AllocFunc allocFunc;
ReallocFunc reallocFunc;
FreeFunc freeFunc;
StringContainerInit2Func stringContainerInit2;
CStringContainerInit2Func cstringContainerInit2;
StringGetMutableDataFunc stringGetMutableData;
CStringGetMutableDataFunc cstringGetMutableData;
void* init3; // obsolete
// Added for Mozilla 1.9
DebugBreakFunc debugBreakFunc;
xpcomVoidFunc logInitFunc;
xpcomVoidFunc logTermFunc;
LogAddRefFunc logAddRefFunc;
LogReleaseFunc logReleaseFunc;
LogCtorFunc logCtorFunc;
LogCtorFunc logDtorFunc;
LogCOMPtrFunc logCOMPtrAddRefFunc;
LogCOMPtrFunc logCOMPtrReleaseFunc;
GetXPTCallStubFunc getXPTCallStubFunc;
DestroyXPTCallStubFunc destroyXPTCallStubFunc;
InvokeByIndexFunc invokeByIndexFunc;
CycleCollectorFunc cycleSuspectFunc; // obsolete: use cycleSuspect3Func
CycleCollectorFunc cycleForgetFunc; // obsolete
StringSetIsVoidFunc stringSetIsVoid;
StringGetIsVoidFunc stringGetIsVoid;
CStringSetIsVoidFunc cstringSetIsVoid;
CStringGetIsVoidFunc cstringGetIsVoid;
// Added for Mozilla 1.9
DebugBreakFunc debugBreakFunc;
xpcomVoidFunc logInitFunc;
xpcomVoidFunc logTermFunc;
LogAddRefFunc logAddRefFunc;
LogReleaseFunc logReleaseFunc;
LogCtorFunc logCtorFunc;
LogCtorFunc logDtorFunc;
LogCOMPtrFunc logCOMPtrAddRefFunc;
LogCOMPtrFunc logCOMPtrReleaseFunc;
GetXPTCallStubFunc getXPTCallStubFunc;
DestroyXPTCallStubFunc destroyXPTCallStubFunc;
InvokeByIndexFunc invokeByIndexFunc;
CycleCollectorFunc cycleSuspectFunc; // obsolete: use cycleSuspect3Func
CycleCollectorFunc cycleForgetFunc; // obsolete
StringSetIsVoidFunc stringSetIsVoid;
StringGetIsVoidFunc stringGetIsVoid;
CStringSetIsVoidFunc cstringSetIsVoid;
CStringGetIsVoidFunc cstringGetIsVoid;
// Added for Mozilla 1.9.1
CycleCollectorSuspect2Func cycleSuspect2Func; // obsolete: use cycleSuspect3Func
CycleCollectorForget2Func cycleForget2Func; // obsolete
// Added for Mozilla 1.9.1
CycleCollectorSuspect2Func cycleSuspect2Func; // obsolete: use cycleSuspect3Func
CycleCollectorForget2Func cycleForget2Func; // obsolete
CycleCollectorSuspect3Func cycleSuspect3Func;
CycleCollectorSuspect3Func cycleSuspect3Func;
} XPCOMFunctions;
typedef nsresult (*GetFrozenFunctionsFunc)(XPCOMFunctions *entryPoints, const char* libraryPath);
XPCOM_API(nsresult)
NS_GetFrozenFunctions(XPCOMFunctions *entryPoints, const char* libraryPath);
typedef nsresult (*GetFrozenFunctionsFunc)(XPCOMFunctions* aEntryPoints,
const char* aLibraryPath);
XPCOM_API(nsresult) NS_GetFrozenFunctions(XPCOMFunctions* aEntryPoints,
const char* aLibraryPath);
namespace mozilla {
/**
* Shutdown XPCOM. You must call this method after you are finished
* using xpcom.
* using xpcom.
*
* @param servMgr The service manager which was returned by NS_InitXPCOM.
* @param aServMgr The service manager which was returned by NS_InitXPCOM.
* This will release servMgr. You may pass null.
*
* @return NS_OK for success;
@ -191,7 +216,7 @@ namespace mozilla {
*
*/
nsresult
ShutdownXPCOM(nsIServiceManager* servMgr);
ShutdownXPCOM(nsIServiceManager* aServMgr);
void SetICUMemoryFunctions();
@ -209,9 +234,9 @@ void LogTerm();
/* XPCOM Specific Defines
*
* XPCOM_DLL - name of the loadable xpcom library on disk.
* XPCOM_DLL - name of the loadable xpcom library on disk.
* XUL_DLL - name of the loadable XUL library on disk
* XPCOM_SEARCH_KEY - name of the environment variable that can be
* XPCOM_SEARCH_KEY - name of the environment variable that can be
* modified to include additional search paths.
* GRE_CONF_NAME - Name of the GRE Configuration file
*/
@ -232,7 +257,7 @@ void LogTerm();
#define XPCOM_DLL XUL_DLL
// you have to love apple..
#ifdef XP_MACOSX
#ifdef XP_MACOSX
#define XPCOM_SEARCH_KEY "DYLD_LIBRARY_PATH"
#define GRE_FRAMEWORK_NAME "XUL.framework"
#define XUL_DLL "XUL"

View File

@ -12,10 +12,10 @@
/* ------------------------------------------------------------------------- */
XPCOM_API(nsresult)
NS_StringContainerInit(nsStringContainer &aContainer)
NS_StringContainerInit(nsStringContainer& aContainer)
{
NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsString),
"nsStringContainer is not large enough");
"nsStringContainer is not large enough");
// use placement new to avoid heap allocating nsString object
new (&aContainer) nsString();
@ -24,44 +24,40 @@ NS_StringContainerInit(nsStringContainer &aContainer)
}
XPCOM_API(nsresult)
NS_StringContainerInit2(nsStringContainer &aContainer,
const char16_t *aData,
uint32_t aDataLength,
uint32_t aFlags)
NS_StringContainerInit2(nsStringContainer& aContainer,
const char16_t* aData,
uint32_t aDataLength,
uint32_t aFlags)
{
NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsString),
"nsStringContainer is not large enough");
"nsStringContainer is not large enough");
if (!aData)
{
if (!aData) {
new (&aContainer) nsString();
}
else
{
if (aDataLength == UINT32_MAX)
{
if (NS_WARN_IF(aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING))
return NS_ERROR_INVALID_ARG;
} else {
if (aDataLength == UINT32_MAX) {
if (NS_WARN_IF(aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING)) {
return NS_ERROR_INVALID_ARG;
}
aDataLength = nsCharTraits<char16_t>::length(aData);
}
if (aFlags & (NS_STRING_CONTAINER_INIT_DEPEND |
NS_STRING_CONTAINER_INIT_ADOPT))
{
NS_STRING_CONTAINER_INIT_ADOPT)) {
uint32_t flags;
if (aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING)
if (aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING) {
flags = nsSubstring::F_NONE;
else
} else {
flags = nsSubstring::F_TERMINATED;
}
if (aFlags & NS_STRING_CONTAINER_INIT_ADOPT)
if (aFlags & NS_STRING_CONTAINER_INIT_ADOPT) {
flags |= nsSubstring::F_OWNED;
}
new (&aContainer) nsSubstring(const_cast<char16_t *>(aData),
new (&aContainer) nsSubstring(const_cast<char16_t*>(aData),
aDataLength, flags);
}
else
{
} else {
new (&aContainer) nsString(aData, aDataLength);
}
}
@ -70,20 +66,21 @@ NS_StringContainerInit2(nsStringContainer &aContainer,
}
XPCOM_API(void)
NS_StringContainerFinish(nsStringContainer &aContainer)
NS_StringContainerFinish(nsStringContainer& aContainer)
{
// call the nsString dtor
reinterpret_cast<nsString *>(&aContainer)->~nsString();
reinterpret_cast<nsString*>(&aContainer)->~nsString();
}
/* ------------------------------------------------------------------------- */
XPCOM_API(uint32_t)
NS_StringGetData(const nsAString &aStr, const char16_t **aData,
bool *aTerminated)
NS_StringGetData(const nsAString& aStr, const char16_t** aData,
bool* aTerminated)
{
if (aTerminated)
if (aTerminated) {
*aTerminated = aStr.IsTerminated();
}
nsAString::const_iterator begin;
aStr.BeginReading(begin);
@ -92,8 +89,8 @@ NS_StringGetData(const nsAString &aStr, const char16_t **aData,
}
XPCOM_API(uint32_t)
NS_StringGetMutableData(nsAString &aStr, uint32_t aDataLength,
char16_t **aData)
NS_StringGetMutableData(nsAString& aStr, uint32_t aDataLength,
char16_t** aData)
{
if (aDataLength != UINT32_MAX) {
aStr.SetLength(aDataLength);
@ -109,63 +106,64 @@ NS_StringGetMutableData(nsAString &aStr, uint32_t aDataLength,
return begin.size_forward();
}
XPCOM_API(char16_t *)
NS_StringCloneData(const nsAString &aStr)
XPCOM_API(char16_t*)
NS_StringCloneData(const nsAString& aStr)
{
return ToNewUnicode(aStr);
}
XPCOM_API(nsresult)
NS_StringSetData(nsAString &aStr, const char16_t *aData, uint32_t aDataLength)
NS_StringSetData(nsAString& aStr, const char16_t* aData, uint32_t aDataLength)
{
aStr.Assign(aData, aDataLength);
return NS_OK; // XXX report errors
}
XPCOM_API(nsresult)
NS_StringSetDataRange(nsAString &aStr,
NS_StringSetDataRange(nsAString& aStr,
uint32_t aCutOffset, uint32_t aCutLength,
const char16_t *aData, uint32_t aDataLength)
const char16_t* aData, uint32_t aDataLength)
{
if (aCutOffset == UINT32_MAX)
{
if (aCutOffset == UINT32_MAX) {
// append case
if (aData)
if (aData) {
aStr.Append(aData, aDataLength);
}
return NS_OK; // XXX report errors
}
if (aCutLength == UINT32_MAX)
if (aCutLength == UINT32_MAX) {
aCutLength = aStr.Length() - aCutOffset;
if (aData)
{
if (aDataLength == UINT32_MAX)
aStr.Replace(aCutOffset, aCutLength, nsDependentString(aData));
else
aStr.Replace(aCutOffset, aCutLength, Substring(aData, aDataLength));
}
else
if (aData) {
if (aDataLength == UINT32_MAX) {
aStr.Replace(aCutOffset, aCutLength, nsDependentString(aData));
} else {
aStr.Replace(aCutOffset, aCutLength, Substring(aData, aDataLength));
}
} else {
aStr.Cut(aCutOffset, aCutLength);
}
return NS_OK; // XXX report errors
}
XPCOM_API(nsresult)
NS_StringCopy(nsAString &aDest, const nsAString &aSrc)
NS_StringCopy(nsAString& aDest, const nsAString& aSrc)
{
aDest.Assign(aSrc);
return NS_OK; // XXX report errors
}
XPCOM_API(void)
NS_StringSetIsVoid(nsAString &aStr, const bool aIsVoid)
NS_StringSetIsVoid(nsAString& aStr, const bool aIsVoid)
{
aStr.SetIsVoid(aIsVoid);
}
XPCOM_API(bool)
NS_StringGetIsVoid(const nsAString &aStr)
NS_StringGetIsVoid(const nsAString& aStr)
{
return aStr.IsVoid();
}
@ -173,10 +171,10 @@ NS_StringGetIsVoid(const nsAString &aStr)
/* ------------------------------------------------------------------------- */
XPCOM_API(nsresult)
NS_CStringContainerInit(nsCStringContainer &aContainer)
NS_CStringContainerInit(nsCStringContainer& aContainer)
{
NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsCString),
"nsCStringContainer is not large enough");
"nsCStringContainer is not large enough");
// use placement new to avoid heap allocating nsCString object
new (&aContainer) nsCString();
@ -185,44 +183,40 @@ NS_CStringContainerInit(nsCStringContainer &aContainer)
}
XPCOM_API(nsresult)
NS_CStringContainerInit2(nsCStringContainer &aContainer,
const char *aData,
uint32_t aDataLength,
uint32_t aFlags)
NS_CStringContainerInit2(nsCStringContainer& aContainer,
const char* aData,
uint32_t aDataLength,
uint32_t aFlags)
{
NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsCString),
"nsStringContainer is not large enough");
"nsStringContainer is not large enough");
if (!aData)
{
if (!aData) {
new (&aContainer) nsCString();
}
else
{
if (aDataLength == UINT32_MAX)
{
if (NS_WARN_IF(aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING))
return NS_ERROR_INVALID_ARG;
} else {
if (aDataLength == UINT32_MAX) {
if (NS_WARN_IF(aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING)) {
return NS_ERROR_INVALID_ARG;
}
aDataLength = nsCharTraits<char>::length(aData);
}
if (aFlags & (NS_CSTRING_CONTAINER_INIT_DEPEND |
NS_CSTRING_CONTAINER_INIT_ADOPT))
{
NS_CSTRING_CONTAINER_INIT_ADOPT)) {
uint32_t flags;
if (aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING)
if (aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING) {
flags = nsCSubstring::F_NONE;
else
} else {
flags = nsCSubstring::F_TERMINATED;
}
if (aFlags & NS_CSTRING_CONTAINER_INIT_ADOPT)
if (aFlags & NS_CSTRING_CONTAINER_INIT_ADOPT) {
flags |= nsCSubstring::F_OWNED;
}
new (&aContainer) nsCSubstring(const_cast<char *>(aData),
new (&aContainer) nsCSubstring(const_cast<char*>(aData),
aDataLength, flags);
}
else
{
} else {
new (&aContainer) nsCString(aData, aDataLength);
}
}
@ -231,20 +225,21 @@ NS_CStringContainerInit2(nsCStringContainer &aContainer,
}
XPCOM_API(void)
NS_CStringContainerFinish(nsCStringContainer &aContainer)
NS_CStringContainerFinish(nsCStringContainer& aContainer)
{
// call the nsCString dtor
reinterpret_cast<nsCString *>(&aContainer)->~nsCString();
reinterpret_cast<nsCString*>(&aContainer)->~nsCString();
}
/* ------------------------------------------------------------------------- */
XPCOM_API(uint32_t)
NS_CStringGetData(const nsACString &aStr, const char **aData,
bool *aTerminated)
NS_CStringGetData(const nsACString& aStr, const char** aData,
bool* aTerminated)
{
if (aTerminated)
if (aTerminated) {
*aTerminated = aStr.IsTerminated();
}
nsACString::const_iterator begin;
aStr.BeginReading(begin);
@ -253,7 +248,7 @@ NS_CStringGetData(const nsACString &aStr, const char **aData,
}
XPCOM_API(uint32_t)
NS_CStringGetMutableData(nsACString &aStr, uint32_t aDataLength, char **aData)
NS_CStringGetMutableData(nsACString& aStr, uint32_t aDataLength, char** aData)
{
if (aDataLength != UINT32_MAX) {
aStr.SetLength(aDataLength);
@ -269,63 +264,64 @@ NS_CStringGetMutableData(nsACString &aStr, uint32_t aDataLength, char **aData)
return begin.size_forward();
}
XPCOM_API(char *)
NS_CStringCloneData(const nsACString &aStr)
XPCOM_API(char*)
NS_CStringCloneData(const nsACString& aStr)
{
return ToNewCString(aStr);
}
XPCOM_API(nsresult)
NS_CStringSetData(nsACString &aStr, const char *aData, uint32_t aDataLength)
NS_CStringSetData(nsACString& aStr, const char* aData, uint32_t aDataLength)
{
aStr.Assign(aData, aDataLength);
return NS_OK; // XXX report errors
}
XPCOM_API(nsresult)
NS_CStringSetDataRange(nsACString &aStr,
NS_CStringSetDataRange(nsACString& aStr,
uint32_t aCutOffset, uint32_t aCutLength,
const char *aData, uint32_t aDataLength)
const char* aData, uint32_t aDataLength)
{
if (aCutOffset == UINT32_MAX)
{
if (aCutOffset == UINT32_MAX) {
// append case
if (aData)
if (aData) {
aStr.Append(aData, aDataLength);
}
return NS_OK; // XXX report errors
}
if (aCutLength == UINT32_MAX)
if (aCutLength == UINT32_MAX) {
aCutLength = aStr.Length() - aCutOffset;
if (aData)
{
if (aDataLength == UINT32_MAX)
aStr.Replace(aCutOffset, aCutLength, nsDependentCString(aData));
else
aStr.Replace(aCutOffset, aCutLength, Substring(aData, aDataLength));
}
else
if (aData) {
if (aDataLength == UINT32_MAX) {
aStr.Replace(aCutOffset, aCutLength, nsDependentCString(aData));
} else {
aStr.Replace(aCutOffset, aCutLength, Substring(aData, aDataLength));
}
} else {
aStr.Cut(aCutOffset, aCutLength);
}
return NS_OK; // XXX report errors
}
XPCOM_API(nsresult)
NS_CStringCopy(nsACString &aDest, const nsACString &aSrc)
NS_CStringCopy(nsACString& aDest, const nsACString& aSrc)
{
aDest.Assign(aSrc);
return NS_OK; // XXX report errors
}
XPCOM_API(void)
NS_CStringSetIsVoid(nsACString &aStr, const bool aIsVoid)
NS_CStringSetIsVoid(nsACString& aStr, const bool aIsVoid)
{
aStr.SetIsVoid(aIsVoid);
}
XPCOM_API(bool)
NS_CStringGetIsVoid(const nsACString &aStr)
NS_CStringGetIsVoid(const nsACString& aStr)
{
return aStr.IsVoid();
}
@ -333,12 +329,11 @@ NS_CStringGetIsVoid(const nsACString &aStr)
/* ------------------------------------------------------------------------- */
XPCOM_API(nsresult)
NS_CStringToUTF16(const nsACString &aSrc,
NS_CStringToUTF16(const nsACString& aSrc,
nsCStringEncoding aSrcEncoding,
nsAString &aDest)
nsAString& aDest)
{
switch (aSrcEncoding)
{
switch (aSrcEncoding) {
case NS_CSTRING_ENCODING_ASCII:
CopyASCIItoUTF16(aSrc, aDest);
break;
@ -356,12 +351,11 @@ NS_CStringToUTF16(const nsACString &aSrc,
}
XPCOM_API(nsresult)
NS_UTF16ToCString(const nsAString &aSrc,
NS_UTF16ToCString(const nsAString& aSrc,
nsCStringEncoding aDestEncoding,
nsACString &aDest)
nsACString& aDest)
{
switch (aDestEncoding)
{
switch (aDestEncoding) {
case NS_CSTRING_ENCODING_ASCII:
LossyCopyUTF16toASCII(aSrc, aDest);
break;

File diff suppressed because it is too large Load Diff

View File

@ -37,26 +37,26 @@ struct nsXREAppData
* mixed-case, e.g. "Mozilla". Optional (may be null), but highly
* recommended. Must not be the empty string.
*/
const char *vendor;
const char* vendor;
/**
* The name of the application. This must be ASCII, and is normally
* mixed-case, e.g. "Firefox". Required (must not be null or an empty
* string).
*/
const char *name;
const char* name;
/**
* The major version, e.g. "0.8.0+". Optional (may be null), but
* required for advanced application features such as the extension
* manager and update service. Must not be the empty string.
*/
const char *version;
const char* version;
/**
* The application's build identifier, e.g. "2004051604"
*/
const char *buildID;
const char* buildID;
/**
* The application's UUID. Used by the extension manager to determine
@ -68,13 +68,13 @@ struct nsXREAppData
* a more readable form is encouraged: "appname@vendor.tld". Only
* the following characters are allowed: a-z A-Z 0-9 - . @ _ { } *
*/
const char *ID;
const char* ID;
/**
* The copyright information to print for the -h commandline flag,
* e.g. "Copyright (c) 2003 mozilla.org".
*/
const char *copyright;
const char* copyright;
/**
* Combination of NS_XRE_ prefixed flags (defined below).
@ -90,13 +90,13 @@ struct nsXREAppData
/**
* The minimum/maximum compatible XRE version.
*/
const char *minVersion;
const char *maxVersion;
const char* minVersion;
const char* maxVersion;
/**
* The server URL to send crash reports to.
*/
const char *crashReporterURL;
const char* crashReporterURL;
/**
* The profile directory that will be used. Optional (may be null). Must not
@ -113,12 +113,12 @@ struct nsXREAppData
*
* UAppData = $HOME/$profile
*/
const char *profile;
const char* profile;
/**
* The application name to use in the User Agent string.
*/
const char *UAName;
const char* UAName;
};
/**

View File

@ -126,9 +126,9 @@
#define XRE_UPDATE_ROOT_DIR "UpdRootD"
/**
* A directory service key which provides an alternate location
* to UpdRootD to to store large files. This key is currently
* only implemented in the Gonk directory service provider.
* A directory service key which provides an alternate location
* to UpdRootD to to store large files. This key is currently
* only implemented in the Gonk directory service provider.
*/
#define XRE_UPDATE_ARCHIVE_DIR "UpdArchD"
@ -176,16 +176,16 @@ XRE_API(int,
* @note Pass UTF8 strings on Windows... native charset on other platforms.
*/
XRE_API(nsresult,
XRE_GetFileFromPath, (const char *aPath, nsIFile* *aResult))
XRE_GetFileFromPath, (const char* aPath, nsIFile** aResult))
/**
* Get the path of the running application binary and store it in aResult.
* @param argv0 The value passed as argv[0] of main(). This value is only
* @param aArgv0 The value passed as argv[0] of main(). This value is only
* used on *nix, and only when other methods of determining
* the binary path have failed.
*/
XRE_API(nsresult,
XRE_GetBinaryPath, (const char *argv0, nsIFile* *aResult))
XRE_GetBinaryPath, (const char* aArgv0, nsIFile** aResult))
/**
* Get the static module built in to libxul.
@ -202,7 +202,7 @@ XRE_API(const mozilla::Module*,
*/
XRE_API(nsresult,
XRE_LockProfileDirectory, (nsIFile* aDirectory,
nsISupports* *aLockObject))
nsISupports** aLockObject))
/**
* Initialize libXUL for embedding purposes.
@ -225,9 +225,9 @@ XRE_API(nsresult,
*/
XRE_API(nsresult,
XRE_InitEmbedding2, (nsIFile *aLibXULDirectory,
nsIFile *aAppDirectory,
nsIDirectoryServiceProvider *aAppDirProvider))
XRE_InitEmbedding2, (nsIFile* aLibXULDirectory,
nsIFile* aAppDirectory,
nsIDirectoryServiceProvider* aAppDirProvider))
/**
* Register static XPCOM component information.
@ -329,7 +329,7 @@ XRE_API(void,
*/
XRE_API(nsresult,
XRE_CreateAppData, (nsIFile* aINIFile,
nsXREAppData **aAppData))
nsXREAppData** aAppData))
/**
* Parse an INI file (application.ini or override.ini) into an existing
@ -340,15 +340,16 @@ XRE_API(nsresult,
*/
XRE_API(nsresult,
XRE_ParseAppData, (nsIFile* aINIFile,
nsXREAppData *aAppData))
nsXREAppData* aAppData))
/**
* Free a nsXREAppData structure that was allocated with XRE_CreateAppData.
*/
XRE_API(void,
XRE_FreeAppData, (nsXREAppData *aAppData))
XRE_FreeAppData, (nsXREAppData* aAppData))
enum GeckoProcessType {
enum GeckoProcessType
{
GeckoProcessType_Default = 0,
GeckoProcessType_Plugin,
@ -444,8 +445,8 @@ XRE_API(void,
XRE_StartupTimelineRecord, (int aEvent, PRTime aWhen))
XRE_API(void,
XRE_InitOmnijar, (nsIFile* greOmni,
nsIFile* appOmni))
XRE_InitOmnijar, (nsIFile* aGreOmni,
nsIFile* aAppOmni))
XRE_API(void,
XRE_StopLateWriteChecks, (void))
@ -453,7 +454,8 @@ XRE_API(void,
/**
* Valid environment types for XRE_GetWindowsEnvironment.
*/
enum WindowsEnvironmentType {
enum WindowsEnvironmentType
{
WindowsEnvironmentType_Desktop = 0,
WindowsEnvironmentType_Metro = 1
};
@ -468,7 +470,7 @@ XRE_API(WindowsEnvironmentType,
#ifdef MOZ_B2G_LOADER
XRE_API(int,
XRE_ProcLoaderServiceRun, (pid_t, int, int argc, const char *argv[]));
XRE_ProcLoaderServiceRun, (pid_t, int, int argc, const char* argv[]));
XRE_API(void,
XRE_ProcLoaderClientInit, (pid_t, int));
XRE_API(void,

View File

@ -17,12 +17,13 @@ namespace mozilla {
namespace probes {
#if defined(MOZ_LOGGING)
static PRLogModuleInfo *
static PRLogModuleInfo*
GetProbeLog()
{
static PRLogModuleInfo *sLog;
if (!sLog)
static PRLogModuleInfo* sLog;
if (!sLog) {
sLog = PR_NewLogModule("SysProbe");
}
return sLog;
}
#define LOG(x) PR_LOG(GetProbeLog(), PR_LOG_DEBUG, x)
@ -30,38 +31,40 @@ GetProbeLog()
#define LOG(x)
#endif
//Utility function
GUID CID_to_GUID(const nsCID &aCID)
// Utility function
GUID
CID_to_GUID(const nsCID& aCID)
{
GUID result;
result.Data1 = aCID.m0;
result.Data2 = aCID.m1;
result.Data3 = aCID.m2;
for (int i = 0; i < 8; ++i)
for (int i = 0; i < 8; ++i) {
result.Data4[i] = aCID.m3[i];
}
return result;
}
// Implementation of Probe
Probe::Probe(const nsCID &aGUID,
const nsACString &aName,
ProbeManager *aManager)
Probe::Probe(const nsCID& aGUID,
const nsACString& aName,
ProbeManager* aManager)
: mGUID(CID_to_GUID(aGUID))
, mName(aName)
, mManager(aManager)
{
}
nsresult Probe::Trigger()
nsresult
Probe::Trigger()
{
if (!(mManager->mIsActive)) {
//Do not trigger if there is no session
return NS_OK;
return NS_OK;
}
_EVENT_TRACE_HEADER event;
ZeroMemory(&event, sizeof(event));
event.Size = sizeof(event);
@ -70,25 +73,33 @@ nsresult Probe::Trigger()
event.Class.Type = 1;
event.Class.Version = 0;
event.Class.Level = TRACE_LEVEL_INFORMATION;
ULONG result = TraceEvent(mManager->mSessionHandle, &event);
LOG(("Probes: Triggered %s, %s, %ld",
mName.Data(),
result==ERROR_SUCCESS ? "success":"failure",
result == ERROR_SUCCESS ? "success" : "failure",
result));
nsresult rv;
switch(result)
{
case ERROR_SUCCESS: rv = NS_OK; break;
switch (result) {
case ERROR_SUCCESS:
rv = NS_OK;
break;
case ERROR_INVALID_FLAG_NUMBER:
case ERROR_MORE_DATA:
case ERROR_INVALID_PARAMETER: rv = NS_ERROR_INVALID_ARG; break;
case ERROR_INVALID_HANDLE: rv = NS_ERROR_FAILURE; break;
case ERROR_INVALID_PARAMETER:
rv = NS_ERROR_INVALID_ARG;
break;
case ERROR_INVALID_HANDLE:
rv = NS_ERROR_FAILURE;
break;
case ERROR_NOT_ENOUGH_MEMORY:
case ERROR_OUTOFMEMORY: rv = NS_ERROR_OUT_OF_MEMORY; break;
default: rv = NS_ERROR_UNEXPECTED;
case ERROR_OUTOFMEMORY:
rv = NS_ERROR_OUT_OF_MEMORY;
break;
default:
rv = NS_ERROR_UNEXPECTED;
}
return rv;
}
@ -104,8 +115,8 @@ ProbeManager::~ProbeManager()
}
}
ProbeManager::ProbeManager(const nsCID &aApplicationUID,
const nsACString &aApplicationName)
ProbeManager::ProbeManager(const nsCID& aApplicationUID,
const nsACString& aApplicationName)
: mApplicationUID(aApplicationUID)
, mApplicationName(aApplicationName)
, mSessionHandle(0)
@ -126,27 +137,24 @@ ProbeManager::ProbeManager(const nsCID &aApplicationUID,
//- in that callback, request the session handle through
// GetTraceLoggerHandle and some opaque value received by the callback
ULONG WINAPI ControlCallback(
WMIDPREQUESTCODE RequestCode,
PVOID Context,
ULONG *Reserved,
PVOID Buffer
)
ULONG WINAPI
ControlCallback(WMIDPREQUESTCODE aRequestCode,
PVOID aContext,
ULONG* aReserved,
PVOID aBuffer)
{
ProbeManager* context = (ProbeManager*)Context;
switch(RequestCode)
{
case WMI_ENABLE_EVENTS:
{
ProbeManager* context = (ProbeManager*)aContext;
switch (aRequestCode) {
case WMI_ENABLE_EVENTS: {
context->mIsActive = true;
TRACEHANDLE sessionHandle = GetTraceLoggerHandle(Buffer);
TRACEHANDLE sessionHandle = GetTraceLoggerHandle(aBuffer);
//Note: We only accept one handle
if ((HANDLE)sessionHandle == INVALID_HANDLE_VALUE) {
ULONG result = GetLastError();
LOG(("Probes: ControlCallback failed, %ul", result));
return result;
} else if (context->mIsActive && context->mSessionHandle
&& context->mSessionHandle != sessionHandle) {
} else if (context->mIsActive && context->mSessionHandle &&
context->mSessionHandle != sessionHandle) {
LOG(("Probes: Can only handle one context at a time, "
"ignoring activation"));
return ERROR_SUCCESS;
@ -157,68 +165,72 @@ ULONG WINAPI ControlCallback(
}
}
case WMI_DISABLE_EVENTS:
context->mIsActive = false;
context->mSessionHandle = 0;
LOG(("Probes: ControlCallback deactivated"));
return ERROR_SUCCESS;
case WMI_DISABLE_EVENTS:
context->mIsActive = false;
context->mSessionHandle = 0;
LOG(("Probes: ControlCallback deactivated"));
return ERROR_SUCCESS;
default:
LOG(("Probes: ControlCallback does not know what to do with %d",
RequestCode));
return ERROR_INVALID_PARAMETER;
default:
LOG(("Probes: ControlCallback does not know what to do with %d",
aRequestCode));
return ERROR_INVALID_PARAMETER;
}
}
already_AddRefed<Probe> ProbeManager::GetProbe(const nsCID &eventUID,
const nsACString &eventName)
already_AddRefed<Probe>
ProbeManager::GetProbe(const nsCID& aEventUID, const nsACString& aEventName)
{
nsRefPtr<Probe> result(new Probe(eventUID, eventName, this));
nsRefPtr<Probe> result(new Probe(aEventUID, aEventName, this));
mAllProbes.AppendElement(result);
return result.forget();
}
nsresult ProbeManager::StartSession()
nsresult
ProbeManager::StartSession()
{
return StartSession(mAllProbes);
}
nsresult ProbeManager::StartSession(nsTArray<nsRefPtr<Probe>> &aProbes)
nsresult
ProbeManager::StartSession(nsTArray<nsRefPtr<Probe>>& aProbes)
{
const size_t probesCount = aProbes.Length();
_TRACE_GUID_REGISTRATION* probes = new _TRACE_GUID_REGISTRATION[probesCount];
for (unsigned int i = 0; i < probesCount; ++i) {
const Probe *probe = aProbes[i];
const Probe *probeX = static_cast<const Probe*>(probe);
probes[i].Guid = (LPCGUID)&(probeX->mGUID);
const Probe* probe = aProbes[i];
const Probe* probeX = static_cast<const Probe*>(probe);
probes[i].Guid = (LPCGUID)&probeX->mGUID;
}
ULONG result =
RegisterTraceGuids(&ControlCallback
/*RequestAddress: Sets mSessions appropriately.*/,
this
/*RequestContext: Passed to ControlCallback*/,
(LPGUID)&mApplicationUID
/*ControlGuid: Tracing GUID
the cast comes from MSDN examples*/,
probesCount
/*GuidCount: Number of probes*/,
probes
/*TraceGuidReg: Probes registration*/,
nullptr
/*MofImagePath: Must be nullptr, says MSDN*/,
nullptr
/*MofResourceName:Must be nullptr, says MSDN*/,
&mRegistrationHandle
/*RegistrationHandle: Handler.
used only for unregistration*/
);
/*RequestAddress: Sets mSessions appropriately.*/,
this
/*RequestContext: Passed to ControlCallback*/,
(LPGUID)&mApplicationUID
/*ControlGuid: Tracing GUID
the cast comes from MSDN examples*/,
probesCount
/*GuidCount: Number of probes*/,
probes
/*TraceGuidReg: Probes registration*/,
nullptr
/*MofImagePath: Must be nullptr, says MSDN*/,
nullptr
/*MofResourceName:Must be nullptr, says MSDN*/,
&mRegistrationHandle
/*RegistrationHandle: Handler.
used only for unregistration*/
);
delete[] probes;
if (NS_WARN_IF(result != ERROR_SUCCESS))
if (NS_WARN_IF(result != ERROR_SUCCESS)) {
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
nsresult ProbeManager::StopSession()
nsresult
ProbeManager::StopSession()
{
LOG(("Probes: Stopping measures"));
if (mSessionHandle != 0) {
@ -231,6 +243,5 @@ nsresult ProbeManager::StopSession()
return NS_OK;
}
}
}
} // namespace probes
} // namespace mozilla

View File

@ -50,9 +50,7 @@ public:
protected:
~Probe() {};
Probe(const nsCID &aGUID,
const nsACString &aName,
ProbeManager *aManager);
Probe(const nsCID& aGUID, const nsACString& aName, ProbeManager* aManager);
friend class ProbeManager;
protected:
@ -74,7 +72,7 @@ protected:
*
* Note: This is a weak reference to avoid a useless cycle.
*/
class ProbeManager *mManager;
class ProbeManager* mManager;
};
@ -95,17 +93,18 @@ public:
*
* This constructor should be called from the main thread.
*
* @param uid The unique ID of the probe. Under Windows, this unique
* ID must have been previously registered using an external tool.
* @param aApplicationUID The unique ID of the probe. Under Windows, this
* unique ID must have been previously registered using an external tool.
* See MyCategory on http://msdn.microsoft.com/en-us/library/aa364100.aspx
* @param name A name for the probe. Currently used only for logging purposes.
* In the future, may be attached to the data sent to the operating system.
* @param aApplicationName A name for the probe. Currently used only for
* logging purposes. In the future, may be attached to the data sent to the
* operating system.
*
* Note: If two ProbeManagers are constructed with the same uid and/or name,
* behavior is unspecified.
*/
ProbeManager(const nsCID &applicationUID,
const nsACString &applicationName);
ProbeManager(const nsCID& aApplicationUID,
const nsACString& aApplicationName);
/**
* Acquire a probe.
@ -114,10 +113,10 @@ public:
* account
* Note: Can be called only from the main thread.
*
* @param eventUID The unique ID of the probe. Under Windows, this unique
* @param aEventUID The unique ID of the probe. Under Windows, this unique
* ID must have been previously registered using an external tool.
* See MyCategory on http://msdn.microsoft.com/en-us/library/aa364100.aspx
* @param eventMame A name for the probe. Currently used only for logging
* @param aEventName A name for the probe. Currently used only for logging
* purposes. In the
* future, may be attached to the data sent to the operating system.
* @return Either |null| in case of error or a valid |Probe*|.
@ -125,8 +124,8 @@ public:
* Note: If this method is called twice with the same uid and/or name,
* behavior is undefined.
*/
already_AddRefed<Probe> GetProbe(const nsCID &eventUID,
const nsACString &eventName);
already_AddRefed<Probe> GetProbe(const nsCID& aEventUID,
const nsACString& aEventName);
/**
* Start/stop the measuring session.
@ -149,8 +148,9 @@ public:
protected:
~ProbeManager();
nsresult StartSession(nsTArray<nsRefPtr<Probe> > &probes);
nsresult Init(const nsCID &applicationUID, const nsACString &applicationName);
nsresult StartSession(nsTArray<nsRefPtr<Probe>>& aProbes);
nsresult Init(const nsCID& aApplicationUID,
const nsACString& aApplicationName);
protected:
/**
@ -173,7 +173,7 @@ protected:
/**
* All the probes that have been created for this manager.
*/
nsTArray<nsRefPtr<Probe> > mAllProbes;
nsTArray<nsRefPtr<Probe>> mAllProbes;
/**
* Handle used for triggering events
@ -190,15 +190,14 @@ protected:
*/
bool mInitialized;
friend class Probe;//Needs to access |mSessionHandle|
friend ULONG WINAPI ControlCallback(
WMIDPREQUESTCODE RequestCode,
PVOID Context,
ULONG *Reserved,
PVOID Buffer
);//Sets |mSessionHandle|
friend class Probe; // Needs to access |mSessionHandle|
friend ULONG WINAPI ControlCallback(WMIDPREQUESTCODE aRequestCode,
PVOID aContext,
ULONG* aReserved,
PVOID aBuffer); // Sets |mSessionHandle|
};
}
}
} // namespace probes
} // namespace mozilla
#endif //mozilla_perfprobe_h