HRESULT CNodeApplication::Dispatch(IHttpContext* context, IHttpEventProvider* pProvider, CNodeHttpStoredContext** ctx) { HRESULT hr; CheckNull(ctx); CheckNull(context); CheckNull(pProvider); ErrorIf(NULL == (*ctx = new CNodeHttpStoredContext(this, context)), ERROR_NOT_ENOUGH_MEMORY); IHttpModuleContextContainer* moduleContextContainer = context->GetModuleContextContainer(); moduleContextContainer->SetModuleContext(*ctx, this->GetApplicationManager()->GetModuleId()); // increase the pending async opertation count; corresponding decrease happens in // CProtocolBridge::FinalizeResponseCore, possibly after several context switches (*ctx)->IncreasePendingAsyncOperationCount(); CheckError(this->processManager->Dispatch(*ctx)); return S_OK; Error: // on error, nodeContext need not be freed here as it will be deallocated through IHttpStoredContext when the request is finished return hr; }
bool cCardClientRadegast::ProcessECM(const cEcmInfo *ecm, const unsigned char *source, unsigned char *cw) { cMutexLock lock(this); if((!so.Connected() && !Login()) || !CanHandle(ecm->caId)) return false; so.Flush(); int len=SCT_LEN(source); int keynr=-1; switch(ecm->caId>>8) { case 0x01: // Seca keynr=cParseSeca::KeyNr(source)&0x0F; break; case 0x05: // Viaccess keynr=cParseViaccess::KeyNr(source); break; case 0x18: // Nagra2 if(ecm->caId>=0x1801) keynr=(source[7]&0x10) | 0x86; break; } unsigned char buff[512], tmp[10]; StartMsg(buff,1); // CMD_ECM_KEY_ASK AddNano(buff,2,1,ecm->caId>>8); // ECM_NANO_CAID_INDEX (old) AddNano(buff,10,2,ecm->caId); // ECM_NANO_CAID sprintf((char *)tmp,"%08X",ecm->provId); AddNano(buff,6,8,tmp); // ECM_NANO_PROVIDER if(keynr>=0) { sprintf((char *)tmp,"%04X",keynr); AddNano(buff,7,4,tmp); // ECM_NANO_KEYNO } if(!CheckLength(buff,len)) return false; AddNano(buff,3,len,source); // ECM_NANO_PACKET if(!Send(buff) || (len=Recv(buff,sizeof(buff)))<0) return false; if(buff[0]==2) { for(int l=GetNanoStart(buff); l<len; l+=buff[l+1]+2) { switch(buff[l]) { case 0x05: if(buff[l+1]==16) { // check for zero cw, as someone may not send both cw's every time if(!CheckNull(buff+l+ 2,8)) memcpy(cw+0,buff+l+ 2,8); if(!CheckNull(buff+l+10,8)) memcpy(cw+8,buff+l+10,8); return true; } else PRINTF(L_CC_RDGD,"wrong cw length %d from server",buff[l+1]); break; case 0x04: PRINTF(L_CC_ECM,"%s: key not available from server",name); break; default: PRINTF(L_CC_RDGD,"unknown nano %02x in ECM response",buff[l]); break; } } } else PRINTF(L_CC_RDGD,"bad ECM response from server %02x != 02",buff[0]); return false; }
void StarSystemSimulation::Simulate(Entity *simulationParent, float deltaT) { base::Simulate(simulationParent, deltaT); CheckNull(simulationParent); ObejctState *simulationState = simulationParent->GetSimulationState(); CheckNull(simulationState); Matrix4 translateToPosition; translateToPosition.SetIdentityMatrix(); translateToPosition.SetPosition(GGame->GetCamera()->GetPosition()); simulationState->_frame = translateToPosition; }
HRESULT CModuleConfiguration::Initialize(IHttpServer* server, HTTP_MODULE_ID moduleId) { HRESULT hr; CheckNull(server); CheckNull(moduleId); CModuleConfiguration::server = server; CModuleConfiguration::moduleId = moduleId; return S_OK; Error: return hr; }
festring& festring::operator=(cchar* CStr) {DBGEXEC(bugTrackInvalidChars(CStr,strlen(CStr))); CheckNull(CStr); sizetype NewSize = strlen(CStr); if(OwnsData) { if(!REFS(Data) && NewSize <= Reserved) { memcpy(Data, CStr, NewSize); Size = NewSize; return *this; } if(!REFS(Data)--) delete [] &REFS(Data); } if(NewSize) CreateOwnData(CStr, NewSize); else Empty(); return *this; }
HRESULT CNodeApplication::Initialize(PCWSTR scriptName, IHttpContext* context) { HRESULT hr; CheckNull(scriptName); DWORD len = wcslen(scriptName) + 1; ErrorIf(NULL == (this->scriptName = new WCHAR[len]), ERROR_NOT_ENOUGH_MEMORY); wcscpy(this->scriptName, scriptName); ErrorIf(NULL == (this->processManager = new CNodeProcessManager(this, context)), ERROR_NOT_ENOUGH_MEMORY); CheckError(this->processManager->Initialize(context)); CheckError(this->GetApplicationManager()->GetFileWatcher()->WatchFiles( scriptName, CModuleConfiguration::GetWatchedFiles(context), CNodeApplicationManager::OnScriptModified, this->GetApplicationManager(), this)); this->GetApplicationManager()->GetEventProvider()->Log(L"iisnode initialized a new node.js application", WINEVENT_LEVEL_INFO); return S_OK; Error: this->GetApplicationManager()->GetEventProvider()->Log(L"iisnode failed to initialize a new node.js application", WINEVENT_LEVEL_ERROR); this->Cleanup(); return hr; }
festring& festring::operator=(staticstring SStr) {DBGEXEC(bugTrackInvalidChars(SStr.Data,SStr.Size)); CheckNull(SStr.Data); cchar* CStr = SStr.Data; sizetype NewSize = SStr.Size; if(OwnsData) { if(!REFS(Data) && NewSize <= Reserved) { memcpy(Data, CStr, NewSize); Size = NewSize; return *this; } if(!REFS(Data)--) delete [] &REFS(Data); } Size = NewSize; Data = const_cast<char*>(CStr); OwnsData = false; return *this; }
HRESULT CActiveRequestPool::Remove(CNodeHttpStoredContext* context) { HRESULT hr; BOOL signal = FALSE; CheckNull(context); ENTER_CS(this->syncRoot) this->requests.remove(context); if (NULL != this->drainHandle && this->requests.empty()) { signal = TRUE; } LEAVE_CS(this->syncRoot) if (signal) { SetEvent(this->drainHandle); } return S_OK; Error: return hr; }
HRESULT CModuleConfiguration::GetDWORD(IAppHostElement* section, LPCWSTR propertyName, DWORD* value) { HRESULT hr = S_OK; BSTR sysPropertyName = NULL; IAppHostProperty* prop = NULL; VARIANT var; CheckNull(value); *value = 0; VariantInit(&var); ErrorIf(NULL == (sysPropertyName = SysAllocString(propertyName)), ERROR_NOT_ENOUGH_MEMORY); CheckError(section->GetPropertyByName(sysPropertyName, &prop)); CheckError(prop->get_Value(&var)); CheckError(VariantChangeType(&var, &var, 0, VT_UI4)); *value = var.ulVal; Error: VariantClear(&var); if ( sysPropertyName ) { SysFreeString(sysPropertyName); sysPropertyName = NULL; } if (prop) { prop->Release(); prop = NULL; } return hr; }
HRESULT CModuleConfiguration::GetConfigSection(IHttpContext* context, IAppHostElement** section, OLECHAR* configElement) { HRESULT hr = S_OK; BSTR path = NULL; BSTR elementName = NULL; CheckNull(section); *section = NULL; ErrorIf(NULL == (path = SysAllocString(context->GetMetadata()->GetMetaPath())), ERROR_NOT_ENOUGH_MEMORY); ErrorIf(NULL == (elementName = SysAllocString(configElement)), ERROR_NOT_ENOUGH_MEMORY); CheckError(server->GetAdminManager()->GetAdminSection(elementName, path, section)); Error: if (NULL != elementName) { SysFreeString(elementName); elementName = NULL; } if (NULL != path) { SysFreeString(path); path = NULL; } return hr; }
HRESULT CModuleConfiguration::GetDebugPortRange(IHttpContext* ctx, DWORD* start, DWORD* end) { HRESULT hr; CheckNull(start); CheckNull(end); CModuleConfiguration* c = NULL; GetConfig(ctx, &c); if (0 == c->debugPortStart) { CheckNull(c->debugPortRange); LPWSTR dash = c->debugPortRange; while (*dash != L'\0' && *dash != L'-') dash++; ErrorIf(dash == c->debugPortRange, ERROR_INVALID_PARAMETER); c->debugPortStart = _wtoi(c->debugPortRange); ErrorIf(c->debugPortStart < 1025, ERROR_INVALID_PARAMETER); if (*dash != L'\0') { c->debugPortEnd = _wtoi(dash + 1); ErrorIf(c->debugPortEnd < c->debugPortStart || c->debugPortEnd > 65535, ERROR_INVALID_PARAMETER); } else { c->debugPortEnd = c->debugPortStart; } } *start = c->debugPortStart; *end = c->debugPortEnd; return S_OK; Error: if (c) { c->debugPortStart = c->debugPortEnd = 0; } return hr; }
OSStatus AUCarbonViewBase::ComponentEntryDispatch(ComponentParameters *p, AUCarbonViewBase *This) { if (This == NULL) return paramErr; OSStatus result = noErr; switch (p->what) { case kAudioUnitCarbonViewCreateSelect: { AudioUnitCarbonViewCreateGluePB *pb = (AudioUnitCarbonViewCreateGluePB *)p; CheckNull(pb->inAudioUnit); CheckNull(pb->inWindow); CheckNull(pb->inParentControl); CheckNull(pb->inSize); CheckNull(pb->inLocation); CheckNull(pb->outControl); result = This->CreateCarbonView(pb->inAudioUnit, pb->inWindow, pb->inParentControl, *pb->inLocation, *pb->inSize, *pb->outControl); } break; #if !__LP64__ case kAudioUnitCarbonViewSetEventListenerSelect: { AudioUnitCarbonViewSetEventListenerGluePB *pb = (AudioUnitCarbonViewSetEventListenerGluePB *)p; This->SetEventListener(pb->inCallback, pb->inUserData); } break; #endif default: result = ComponentBase::ComponentEntryDispatch(p, This); break; } return result; }
bool cDeCSA::SetDescr(ca_descr_t *ca_descr, bool initial) { cMutexLock lock(&mutex); int idx=ca_descr->index; if(idx<MAX_CSA_IDX && GetKeyStruct(idx)) { if(!initial && ca_descr->parity==(even_odd[idx]&0x40)>>6) { if(flags[idx] & (ca_descr->parity?FL_ODD_GOOD:FL_EVEN_GOOD)) { printf("adapter%d/demux%d idx %d: %s key in use (%d ms)", adapter, demux ,idx,ca_descr->parity?"odd":"even",MAX_REL_WAIT); if(wait.TimedWait(mutex,MAX_REL_WAIT)) printf("adapter%d/demux%d idx %d: successfully waited for release\n", adapter, demux, idx); else printf("adapter%d/demux%d idx %d: timed out. setting anyways\n", adapter, demux, idx); } else printf("adapter%d/demux%d idx %d: late key set...\n", adapter, demux, idx); } if(ca_descr->parity==0) { dvbcsa_bs_key_set(ca_descr->cw, csa_bs_key_even[idx]); if(!CheckNull(ca_descr->cw,8)) flags[idx] |= FL_EVEN_GOOD|FL_ACTIVITY; else printf("adapter%d/demux%d idx %d: zero even CW\n", adapter, demux, idx); wait.Broadcast(); } else { dvbcsa_bs_key_set(ca_descr->cw, csa_bs_key_odd[idx]); if(!CheckNull(ca_descr->cw,8)) flags[idx] |= FL_ODD_GOOD|FL_ACTIVITY; else printf("adapter%d/demux%d idx%d: zero odd CW\n", adapter, demux, idx); wait.Broadcast(); } } return true; }
HRESULT CActiveRequestPool::Add(CNodeHttpStoredContext* context) { HRESULT hr; CheckNull(context); ENTER_CS(this->syncRoot) ErrorIf(this->requests.size() >= CModuleConfiguration::GetMaxConcurrentRequestsPerProcess(context->GetHttpContext()), ERROR_NOT_ENOUGH_QUOTA); this->requests.push_back(context); LEAVE_CS(this->syncRoot) return S_OK; Error: return hr; }
HRESULT CPendingRequestQueue::Push(CNodeHttpStoredContext* context) { HRESULT hr; CheckNull(context); ENTER_CS(this->syncRoot) ErrorIf(this->requests.size() >= CModuleConfiguration::GetMaxPendingRequestsPerApplication(context->GetHttpContext()), ERROR_NOT_ENOUGH_QUOTA); this->requests.push(context); LEAVE_CS(this->syncRoot) return S_OK; Error: return hr; }
HRESULT CNodeApplicationManager::Dispatch(IHttpContext* context, IHttpEventProvider* pProvider, CNodeHttpStoredContext** ctx) { HRESULT hr; CNodeApplication* application; NodeDebugCommand debugCommand; CheckNull(ctx); *ctx = NULL; CheckError(CNodeDebugger::GetDebugCommand(context, this->GetEventProvider(), &debugCommand)); if (ND_KILL == debugCommand) { ENTER_CS(this->syncRoot) CheckError(this->EnsureDebuggedApplicationKilled(context, ctx)); LEAVE_CS(this->syncRoot) }
HRESULT CModuleConfiguration::GetString(IAppHostElement* section, LPCWSTR propertyName, LPWSTR* value) { HRESULT hr = S_OK; BSTR sysPropertyName = NULL; BSTR sysPropertyValue = NULL; IAppHostProperty* prop = NULL; CheckNull(value); *value = NULL; ErrorIf(NULL == (sysPropertyName = SysAllocString(propertyName)), ERROR_NOT_ENOUGH_MEMORY); CheckError(section->GetPropertyByName(sysPropertyName, &prop)); CheckError(prop->get_StringValue(&sysPropertyValue)); ErrorIf(NULL == (*value = new WCHAR[wcslen(sysPropertyValue) + 1]), ERROR_NOT_ENOUGH_MEMORY); wcscpy(*value, sysPropertyValue); Error: if ( sysPropertyName ) { SysFreeString(sysPropertyName); sysPropertyName = NULL; } if ( sysPropertyValue ) { SysFreeString(sysPropertyValue); sysPropertyValue = NULL; } if (prop) { prop->Release(); prop = NULL; } return hr; }
HRESULT CHttpProtocol::SerializeRequestHeaders(CNodeHttpStoredContext* ctx, void** result, DWORD* resultSize, DWORD* resultLength) { HRESULT hr; PCSTR originalUrl = NULL; USHORT originalUrlLength; CheckNull(ctx); CheckNull(result); CheckNull(resultSize); CheckNull(resultLength); IHttpContext* context = ctx->GetHttpContext(); DWORD bufferLength = CModuleConfiguration::GetInitialRequestBufferSize(context); DWORD offset = 0; IHttpRequest* request = context->GetRequest(); HTTP_REQUEST* raw = request->GetRawHttpRequest(); USHORT major, minor; char tmp[256]; PCSTR method = request->GetHttpMethod(); ErrorIf(NULL == (*result = context->AllocateRequestMemory(bufferLength)), ERROR_NOT_ENOUGH_MEMORY); // Determine whether response entity body is to be expected if (method && 0 == strcmpi("HEAD", method)) { // HEAD requests do not have response entity body // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 ctx->SetExpectResponseBody(FALSE); } // Request-Line CheckError(CHttpProtocol::Append(context, method, 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, " ", 1, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ctx->GetTargetUrl(), ctx->GetTargetUrlLength(), result, &bufferLength, &offset)); request->GetHttpVersion(&major, &minor); if (1 == major && 1 == minor) { CheckError(CHttpProtocol::Append(context, " HTTP/1.1\r\n", 11, result, &bufferLength, &offset)); } else if (1 == major && 0 == minor) { CheckError(CHttpProtocol::Append(context, " HTTP/1.0\r\n", 11, result, &bufferLength, &offset)); } else { sprintf(tmp, " HTTP/%d.%d\r\n", major, minor); CheckError(CHttpProtocol::Append(context, tmp, 0, result, &bufferLength, &offset)); } // Known headers for (int i = 0; i < HttpHeaderRequestMaximum; i++) { if (raw->Headers.KnownHeaders[i].RawValueLength > 0) { CheckError(CHttpProtocol::Append(context, CHttpProtocol::httpRequestHeaders[i], 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.KnownHeaders[i].pRawValue, raw->Headers.KnownHeaders[i].RawValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } } // Unknown headers for (int i = 0; i < raw->Headers.UnknownHeaderCount; i++) { CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pName, raw->Headers.pUnknownHeaders[i].NameLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pRawValue, raw->Headers.pUnknownHeaders[i].RawValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } // CRLF CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); *resultSize = bufferLength; *resultLength = offset; return S_OK; Error: if (NULL != result) { *result = NULL; } if (NULL != resultLength) { *resultLength = 0; } if (NULL != resultSize) { *resultSize = 0; } return hr; }
HRESULT CFileWatcher::WatchFiles(PCWSTR mainFileName, PCWSTR watchedFiles, FileModifiedCallback callback, CNodeApplicationManager* manager, CNodeApplication* application) { HRESULT hr; WCHAR fileOnly[_MAX_FNAME]; WCHAR ext[_MAX_EXT]; WCHAR* directoryName = NULL; DWORD fileNameLength; DWORD fileNameOnlyLength; DWORD directoryLength; BOOL unc; BOOL wildcard; PWSTR startSubdirectory; PWSTR startFile; PWSTR endFile; WatchedDirectory* directory; WatchedFile* file; CheckNull(mainFileName); CheckNull(watchedFiles); // create and normalize a copy of directory name, determine if it is UNC share fileNameLength = wcslen(mainFileName); ErrorIf(0 != _wsplitpath_s(mainFileName, NULL, 0, NULL, 0, fileOnly, _MAX_FNAME, ext, _MAX_EXT), ERROR_INVALID_PARAMETER); fileNameOnlyLength = wcslen(fileOnly) + wcslen(ext); directoryLength = fileNameLength - fileNameOnlyLength; ErrorIf(NULL == (directoryName = new WCHAR[directoryLength + 8]), ERROR_NOT_ENOUGH_MEMORY); // pessimistic length after normalization with prefix \\?\UNC\ if (fileNameLength > 8 && 0 == memcmp(mainFileName, L"\\\\?\\UNC\\", 8 * sizeof WCHAR)) { // normalized UNC path unc = TRUE; memcpy(directoryName, mainFileName, directoryLength * sizeof WCHAR); directoryName[directoryLength] = L'\0'; } else if (fileNameLength > 4 && 0 == memcmp(mainFileName, L"\\\\?\\", 4 * sizeof WCHAR)) { // normalized local file unc = FALSE; memcpy(directoryName, mainFileName, directoryLength * sizeof WCHAR); directoryName[directoryLength] = L'\0'; } else if (fileNameLength > 2 && 0 == memcmp(mainFileName, L"\\\\", 2 * sizeof(WCHAR))) { // not normalized UNC path unc = TRUE; wcscpy(directoryName, L"\\\\?\\UNC\\"); memcpy(directoryName + 8, mainFileName + 2, (directoryLength - 2) * sizeof WCHAR); directoryName[8 + directoryLength - 2] = L'\0'; } else { // not normalized local file unc = FALSE; wcscpy(directoryName, L"\\\\?\\"); memcpy(directoryName + 4, mainFileName, directoryLength * sizeof WCHAR); directoryName[4 + directoryLength] = L'\0'; } directoryLength = wcslen(directoryName); ENTER_CS(this->syncRoot) // parse watchedFiles and create a file listener for each of the files startFile = (PWSTR)watchedFiles; do { endFile = startSubdirectory = startFile; wildcard = FALSE; while (*endFile && *endFile != L';') { wildcard |= *endFile == L'*' || *endFile == L'?'; if (*endFile == L'\\') { startFile = endFile + 1; } endFile++; } if (startFile != endFile) { hr = this->WatchFile(directoryName, directoryLength, unc, startSubdirectory, startFile, endFile, wildcard); // ignore files and directories that do not exist instead of failing if (S_OK != hr && ERROR_FILE_NOT_FOUND != hr) { // still under lock remove file watch entries that were just created, then do regular cleanup this->RemoveWatch(NULL); CheckError(hr); } } startFile = endFile + 1; } while(*endFile); // update temporary entries with application and callback pointers directory = this->directories; while (NULL != directory) { file = directory->files; while (NULL != file) { if (NULL == file->application) { file->application = application; file->manager = manager; file->callback = callback; } file = file->next; } directory = directory->next; } LEAVE_CS(this->syncRoot) delete [] directoryName; return S_OK; Error: if (NULL != directoryName) { delete [] directoryName; directoryName = NULL; } return hr; }
HRESULT CHttpProtocol::SerializeRequestHeaders(IHttpContext* context, void** result, DWORD* resultSize, DWORD* resultLength) { HRESULT hr; CheckNull(context); CheckNull(result); CheckNull(resultSize); CheckNull(resultLength); DWORD bufferLength = CModuleConfiguration::GetInitialRequestBufferSize(context); DWORD offset = 0; IHttpRequest* request = context->GetRequest(); HTTP_REQUEST* raw = request->GetRawHttpRequest(); USHORT major, minor; char tmp[256]; ErrorIf(NULL == (*result = context->AllocateRequestMemory(bufferLength)), ERROR_NOT_ENOUGH_MEMORY); // Request-Line CheckError(CHttpProtocol::Append(context, request->GetHttpMethod(), 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, " ", 1, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->pRawUrl, raw->RawUrlLength, result, &bufferLength, &offset)); request->GetHttpVersion(&major, &minor); sprintf(tmp, " HTTP/%d.%d\r\n", major, minor); CheckError(CHttpProtocol::Append(context, tmp, 0, result, &bufferLength, &offset)); // Known headers for (int i = 0; i < HttpHeaderRequestMaximum; i++) { if (raw->Headers.KnownHeaders[i].RawValueLength > 0) { CheckError(CHttpProtocol::Append(context, CHttpProtocol::httpRequestHeaders[i], 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.KnownHeaders[i].pRawValue, raw->Headers.KnownHeaders[i].RawValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } } // Unknown headers for (int i = 0; i < raw->Headers.UnknownHeaderCount; i++) { CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pName, raw->Headers.pUnknownHeaders[i].NameLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pRawValue, raw->Headers.pUnknownHeaders[i].RawValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } // CRLF CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); *resultSize = bufferLength; *resultLength = offset; return S_OK; Error: if (NULL != result) { *result = NULL; } if (NULL != resultLength) { *resultLength = 0; } if (NULL != resultSize) { *resultSize = 0; } return hr; }
HRESULT CHttpProtocol::SerializeRequestHeaders(CNodeHttpStoredContext* ctx, void** result, DWORD* resultSize, DWORD* resultLength) { HRESULT hr; PCSTR originalUrl = NULL; USHORT originalUrlLength; DWORD remoteHostSize = INET6_ADDRSTRLEN + 1; char remoteHost[INET6_ADDRSTRLEN + 1]; BOOL addXFF; char** serverVars; int serverVarCount; CheckNull(ctx); CheckNull(result); CheckNull(resultSize); CheckNull(resultLength); IHttpContext* context = ctx->GetHttpContext(); DWORD bufferLength = CModuleConfiguration::GetInitialRequestBufferSize(context); DWORD offset = 0; IHttpRequest* request = context->GetRequest(); HTTP_REQUEST* raw = request->GetRawHttpRequest(); USHORT major, minor; const int tmpSize = 256; char tmp[tmpSize]; PCSTR method = request->GetHttpMethod(); ErrorIf(NULL == (*result = context->AllocateRequestMemory(bufferLength)), ERROR_NOT_ENOUGH_MEMORY); // Determine whether response entity body is to be expected if (method && 0 == strcmpi("HEAD", method)) { // HEAD requests do not have response entity body // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 ctx->SetExpectResponseBody(FALSE); } // Request-Line CheckError(CHttpProtocol::Append(context, method, 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, " ", 1, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ctx->GetTargetUrl(), ctx->GetTargetUrlLength(), result, &bufferLength, &offset)); request->GetHttpVersion(&major, &minor); if (1 == major && 1 == minor) { CheckError(CHttpProtocol::Append(context, " HTTP/1.1\r\n", 11, result, &bufferLength, &offset)); } else if (1 == major && 0 == minor) { CheckError(CHttpProtocol::Append(context, " HTTP/1.0\r\n", 11, result, &bufferLength, &offset)); } else { sprintf(tmp, " HTTP/%d.%d\r\n", major, minor); CheckError(CHttpProtocol::Append(context, tmp, 0, result, &bufferLength, &offset)); } // Known headers for (int i = 0; i < HttpHeaderRequestMaximum; i++) { if (raw->Headers.KnownHeaders[i].RawValueLength > 0) { CheckError(CHttpProtocol::Append(context, CHttpProtocol::httpRequestHeaders[i], 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.KnownHeaders[i].pRawValue, raw->Headers.KnownHeaders[i].RawValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } } // Unknown headers if (TRUE == (addXFF = CModuleConfiguration::GetEnableXFF(context))) { PSOCKADDR addr = request->GetRemoteAddress(); DWORD addrSize = addr->sa_family == AF_INET ? sizeof SOCKADDR_IN : sizeof SOCKADDR_IN6; ErrorIf(0 != WSAAddressToString(addr, addrSize, NULL, remoteHost, &remoteHostSize), GetLastError()); } for (int i = 0; i < raw->Headers.UnknownHeaderCount; i++) { CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pName, raw->Headers.pUnknownHeaders[i].NameLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pRawValue, raw->Headers.pUnknownHeaders[i].RawValueLength, result, &bufferLength, &offset)); if (addXFF && 15 == raw->Headers.pUnknownHeaders[i].NameLength && 0 == strcmpi("X-Forwarded-For", raw->Headers.pUnknownHeaders[i].pName)) { // augment existing X-Forwarded-For header CheckError(CHttpProtocol::Append(context, ", ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, remoteHost, remoteHostSize - 1, result, &bufferLength, &offset)); addXFF = FALSE; } CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } if (addXFF) { // add a new X-Forwarded-For header CheckError(CHttpProtocol::Append(context, "X-Forwarded-For: ", 17, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, remoteHost, remoteHostSize - 1, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } // promote server variables CheckError(CModuleConfiguration::GetPromoteServerVars(context, &serverVars, &serverVarCount)); while (serverVarCount) { serverVarCount--; PCSTR varValue; DWORD varValueLength; if (S_OK == context->GetServerVariable(serverVars[serverVarCount], &varValue, &varValueLength)) { CheckError(CHttpProtocol::Append(context, "X-iisnode-", 10, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, serverVars[serverVarCount], 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, varValue, varValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } } // CRLF CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); *resultSize = bufferLength; *resultLength = offset; return S_OK; Error: if (NULL != result) { *result = NULL; } if (NULL != resultLength) { *resultLength = 0; } if (NULL != resultSize) { *resultSize = 0; } return hr; }
HRESULT CModuleConfiguration::CreateNodeEnvironment(IHttpContext* ctx, DWORD debugPort, PCH namedPipe, PCH* env) { HRESULT hr; LPCH currentEnvironment = NULL; LPCH tmpStart, tmpIndex = NULL; DWORD tmpSize; DWORD environmentSize; IAppHostElement* section = NULL; IAppHostElementCollection* appSettings = NULL; IAppHostElement* entry = NULL; IAppHostPropertyCollection* properties = NULL; IAppHostProperty* prop = NULL; BSTR keyPropertyName = NULL; BSTR valuePropertyName = NULL; VARIANT vKeyPropertyName; VARIANT vValuePropertyName; DWORD count; BSTR propertyValue; int propertySize; CheckNull(env); *env = NULL; // this is a zero terminated list of zero terminated strings of the form <var>=<value> // calculate size of current environment ErrorIf(NULL == (currentEnvironment = GetEnvironmentStrings()), GetLastError()); environmentSize = 0; do { while (*(currentEnvironment + environmentSize++) != 0); } while (*(currentEnvironment + environmentSize++) != 0); // allocate memory for new environment variables tmpSize = 32767 - environmentSize; ErrorIf(NULL == (tmpIndex = tmpStart = new char[tmpSize]), ERROR_NOT_ENOUGH_MEMORY); RtlZeroMemory(tmpIndex, tmpSize); // set PORT and IISNODE_VERSION variables ErrorIf(tmpSize < (strlen(namedPipe) + strlen(IISNODE_VERSION) + 6 + 17), ERROR_NOT_ENOUGH_MEMORY); sprintf(tmpIndex, "PORT=%s", namedPipe); tmpIndex += strlen(namedPipe) + 6; sprintf(tmpIndex, "IISNODE_VERSION=%s", IISNODE_VERSION); tmpIndex += strlen(IISNODE_VERSION) + 17; // set DEBUGPORT environment variable if requested (used by node-inspector) if (debugPort > 0) { char debugPortS[64]; sprintf(debugPortS, "%d", debugPort); ErrorIf((tmpSize - (tmpIndex - tmpStart)) < (strlen(debugPortS) + 11), ERROR_NOT_ENOUGH_MEMORY); sprintf(tmpIndex, "DEBUGPORT=%s", debugPortS); tmpIndex += strlen(debugPortS) + 11; } // add environment variables from the appSettings section of config ErrorIf(NULL == (keyPropertyName = SysAllocString(L"key")), ERROR_NOT_ENOUGH_MEMORY); vKeyPropertyName.vt = VT_BSTR; vKeyPropertyName.bstrVal = keyPropertyName; ErrorIf(NULL == (valuePropertyName = SysAllocString(L"value")), ERROR_NOT_ENOUGH_MEMORY); vValuePropertyName.vt = VT_BSTR; vValuePropertyName.bstrVal = valuePropertyName; CheckError(GetConfigSection(ctx, §ion, L"appSettings")); CheckError(section->get_Collection(&appSettings)); CheckError(appSettings->get_Count(&count)); for (USHORT i = 0; i < count; i++) { VARIANT index; index.vt = VT_I2; index.iVal = i; CheckError(appSettings->get_Item(index, &entry)); CheckError(entry->get_Properties(&properties)); CheckError(properties->get_Item(vKeyPropertyName, &prop)); CheckError(prop->get_StringValue(&propertyValue)); ErrorIf(0 == (propertySize = WideCharToMultiByte(CP_ACP, 0, propertyValue, wcslen(propertyValue), NULL, 0, NULL, NULL)), E_FAIL); ErrorIf((propertySize + 2) > (tmpSize - (tmpStart - tmpIndex)), ERROR_NOT_ENOUGH_MEMORY); ErrorIf(propertySize != WideCharToMultiByte(CP_ACP, 0, propertyValue, wcslen(propertyValue), tmpIndex, propertySize, NULL, NULL), E_FAIL); tmpIndex[propertySize] = '='; tmpIndex += propertySize + 1; SysFreeString(propertyValue); propertyValue = NULL; prop->Release(); prop = NULL; CheckError(properties->get_Item(vValuePropertyName, &prop)); CheckError(prop->get_StringValue(&propertyValue)); ErrorIf(0 == (propertySize = WideCharToMultiByte(CP_ACP, 0, propertyValue, wcslen(propertyValue), NULL, 0, NULL, NULL)), E_FAIL); ErrorIf((propertySize + 1) > (tmpSize - (tmpStart - tmpIndex)), ERROR_NOT_ENOUGH_MEMORY); ErrorIf(propertySize != WideCharToMultiByte(CP_ACP, 0, propertyValue, wcslen(propertyValue), tmpIndex, propertySize, NULL, NULL), E_FAIL); tmpIndex += propertySize + 1; SysFreeString(propertyValue); propertyValue = NULL; prop->Release(); prop = NULL; properties->Release(); properties = NULL; entry->Release(); entry = NULL; } // concatenate new environment variables with the current environment block ErrorIf(NULL == (*env = (LPCH)new char[environmentSize + (tmpIndex - tmpStart)]), ERROR_NOT_ENOUGH_MEMORY); memcpy(*env, tmpStart, (tmpIndex - tmpStart)); memcpy(*env + (tmpIndex - tmpStart), currentEnvironment, environmentSize); // cleanup FreeEnvironmentStrings(currentEnvironment); section->Release(); appSettings->Release(); SysFreeString(keyPropertyName); SysFreeString(valuePropertyName); delete [] tmpStart; return S_OK; Error: if (currentEnvironment) { FreeEnvironmentStrings(currentEnvironment); currentEnvironment = NULL; } if (section) { section->Release(); section = NULL; } if (appSettings) { appSettings->Release(); appSettings = NULL; } if (keyPropertyName) { SysFreeString(keyPropertyName); keyPropertyName = NULL; } if (valuePropertyName) { SysFreeString(valuePropertyName); valuePropertyName = NULL; } if (entry) { entry->Release(); entry = NULL; } if (properties) { properties->Release(); properties = NULL; } if (prop) { prop->Release(); prop = NULL; } if (propertyValue) { SysFreeString(propertyValue); propertyValue = NULL; } if (tmpStart) { delete [] tmpStart; tmpStart = NULL; } return hr; }
HRESULT CModuleConfiguration::GetConfig(IHttpContext* context, CModuleConfiguration** config) { HRESULT hr; CModuleConfiguration* c = NULL; IAppHostElement* section = NULL; LPWSTR commandLine = NULL; size_t i; CheckNull(config); *config = (CModuleConfiguration*)context->GetMetadata()->GetModuleContextContainer()->GetModuleContext(moduleId); if (NULL == *config) { ErrorIf(NULL == (c = new CModuleConfiguration()), ERROR_NOT_ENOUGH_MEMORY); CheckError(GetConfigSection(context, §ion)); CheckError(GetDWORD(section, L"maxPendingRequestsPerApplication", &c->maxPendingRequestsPerApplication)); CheckError(GetDWORD(section, L"asyncCompletionThreadCount", &c->asyncCompletionThreadCount)); CheckError(GetDWORD(section, L"maxProcessCountPerApplication", &c->maxProcessCountPerApplication)); CheckError(GetDWORD(section, L"maxConcurrentRequestsPerProcess", &c->maxConcurrentRequestsPerProcess)); CheckError(GetDWORD(section, L"maxNamedPipeConnectionRetry", &c->maxNamedPipeConnectionRetry)); CheckError(GetDWORD(section, L"namedPipeConnectionRetryDelay", &c->namedPipeConnectionRetryDelay)); CheckError(GetDWORD(section, L"initialRequestBufferSize", &c->initialRequestBufferSize)); CheckError(GetDWORD(section, L"maxRequestBufferSize", &c->maxRequestBufferSize)); CheckError(GetDWORD(section, L"uncFileChangesPollingInterval", &c->uncFileChangesPollingInterval)); CheckError(GetDWORD(section, L"gracefulShutdownTimeout", &c->gracefulShutdownTimeout)); CheckError(GetDWORD(section, L"logFileFlushInterval", &c->logFileFlushInterval)); CheckError(GetDWORD(section, L"maxLogFileSizeInKB", &c->maxLogFileSizeInKB)); CheckError(GetBOOL(section, L"loggingEnabled", &c->loggingEnabled)); CheckError(GetBOOL(section, L"appendToExistingLog", &c->appendToExistingLog)); CheckError(GetString(section, L"logDirectoryNameSuffix", &c->logDirectoryNameSuffix)); CheckError(GetString(section, L"debuggerPortRange", &c->debugPortRange)); CheckError(GetString(section, L"debuggerPathSegment", &c->debuggerPathSegment)); c->debuggerPathSegmentLength = wcslen(c->debuggerPathSegment); CheckError(GetString(section, L"nodeProcessCommandLine", &commandLine)); ErrorIf(NULL == (c->nodeProcessCommandLine = new char[MAX_PATH]), ERROR_NOT_ENOUGH_MEMORY); ErrorIf(0 != wcstombs_s(&i, c->nodeProcessCommandLine, (size_t)MAX_PATH, commandLine, _TRUNCATE), ERROR_INVALID_PARAMETER); delete [] commandLine; commandLine = NULL; section->Release(); section = NULL; // CR: check for ERROR_ALREADY_ASSIGNED to detect a race in creation of this section // CR: refcounting may be needed if synchronous code paths proove too long (race with config changes) context->GetMetadata()->GetModuleContextContainer()->SetModuleContext(c, moduleId); *config = c; c = NULL; } return S_OK; Error: if (NULL != section) { section->Release(); section = NULL; } if (NULL != commandLine) { delete [] commandLine; commandLine = NULL; } if (NULL != c) { delete c; c = NULL; } return hr; }
HRESULT CFileWatcher::WatchFile(PCWSTR fileName, FileModifiedCallback callback, void* data) { HRESULT hr; WatchedFile* file; WatchedDirectory* directory; WatchedDirectory* newDirectory; WCHAR fileOnly[_MAX_FNAME]; WCHAR ext[_MAX_EXT]; WCHAR* directoryName = NULL; DWORD fileNameLength; DWORD fileNameOnlyLength; DWORD directoryLength; WIN32_FILE_ATTRIBUTE_DATA attributes; CheckNull(callback); CheckNull(fileName); fileNameLength = wcslen(fileName); // allocate new WatchedFile, get snapshot of the last write time ErrorIf(NULL == (file = new WatchedFile), ERROR_NOT_ENOUGH_MEMORY); RtlZeroMemory(file, sizeof WatchedFile); file->callback = callback; file->data = data; ErrorIf(!GetFileAttributesExW(fileName, GetFileExInfoStandard, &attributes), GetLastError()); memcpy(&file->lastWrite, &attributes.ftLastWriteTime, sizeof attributes.ftLastWriteTime); // create and normalize a copy of directory name and file name ErrorIf(0 != _wsplitpath_s(fileName, NULL, 0, NULL, 0, fileOnly, _MAX_FNAME, ext, _MAX_EXT), ERROR_INVALID_PARAMETER); fileNameOnlyLength = wcslen(fileOnly) + wcslen(ext); directoryLength = fileNameLength - fileNameOnlyLength; ErrorIf(NULL == (directoryName = new WCHAR[directoryLength + 8]), ERROR_NOT_ENOUGH_MEMORY); // pessimistic length after normalization with prefix \\?\UNC\ ErrorIf(NULL == (file->fileName = new WCHAR[fileNameLength + 1]), ERROR_NOT_ENOUGH_MEMORY); wcscpy(file->fileName, fileName); if (fileNameLength > 8 && 0 == memcmp(fileName, L"\\\\?\\UNC\\", 8 * sizeof WCHAR)) { // normalized UNC path file->unc = TRUE; memcpy(directoryName, fileName, directoryLength * sizeof WCHAR); directoryName[directoryLength] = L'\0'; } else if (fileNameLength > 4 && 0 == memcmp(fileName, L"\\\\?\\", 4 * sizeof WCHAR)) { // normalized local file file->unc = FALSE; memcpy(directoryName, fileName, directoryLength * sizeof WCHAR); directoryName[directoryLength] = L'\0'; } else if (fileNameLength > 2 && 0 == memcmp(fileName, L"\\\\", 2 * sizeof(WCHAR))) { // not normalized UNC path file->unc = TRUE; wcscpy(directoryName, L"\\\\?\\UNC\\"); memcpy(directoryName + 8, fileName + 2, (directoryLength - 2) * sizeof WCHAR); directoryName[8 + directoryLength - 2] = L'\0'; } else { // not normalized local file file->unc = FALSE; wcscpy(directoryName, L"\\\\?\\"); memcpy(directoryName + 4, fileName, directoryLength * sizeof WCHAR); directoryName[4 + directoryLength] = L'\0'; } // find matching directory watcher entry directory = this->directories; while (NULL != directory) { if (0 == wcscmp(directory->directoryName, directoryName)) { delete [] directoryName; directoryName = NULL; break; } directory = directory->next; } // if directory watcher not found, create one if (NULL == directory) { ErrorIf(NULL == (newDirectory = new WatchedDirectory), ERROR_NOT_ENOUGH_MEMORY); RtlZeroMemory(newDirectory, sizeof WatchedDirectory); newDirectory->directoryName = directoryName; directoryName = NULL; newDirectory->files = file; ErrorIf(INVALID_HANDLE_VALUE == (newDirectory->watchHandle = CreateFileW( newDirectory->directoryName, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL)), GetLastError()); ErrorIf(NULL == CreateIoCompletionPort(newDirectory->watchHandle, this->completionPort, (ULONG_PTR)newDirectory, 0), GetLastError()); ErrorIf(0 == ReadDirectoryChangesW( newDirectory->watchHandle, &newDirectory->info, sizeof newDirectory->info, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, NULL, &newDirectory->overlapped, NULL), GetLastError()); if (NULL == this->directories) { // no watchers exist yet, start the watcher thread ErrorIf(NULL == (this->worker = (HANDLE)_beginthreadex( NULL, 4096, CFileWatcher::Worker, this, 0, NULL)), ERROR_NOT_ENOUGH_MEMORY); } newDirectory->next = this->directories; this->directories = newDirectory; newDirectory = NULL; } else { file->next = directory->files; directory->files = file; file = NULL; } return S_OK; Error: if (NULL != newDirectory) { if (NULL != newDirectory->directoryName) { delete [] newDirectory->directoryName; } if (NULL != newDirectory->watchHandle) { CloseHandle(newDirectory->watchHandle); } delete newDirectory; } if (NULL != file) { delete [] file->fileName; delete file; } if (NULL != directoryName) { delete [] directoryName; } return hr; }