STDMETHODIMP CUUEngine::LastOSError(long *errNo, VARIANT *errMessage, BOOL *gotErr) { long lasterr; char *syserr; if ((lasterr = ::GetLastError()) == 0) { *gotErr = FALSE; return(S_OK); } MString erm; if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, lasterr, GetUserDefaultLangID(), (LPTSTR) &syserr, 0, NULL) == 0) erm = "Unknown Error"; // Couldn't convert error number to string else { erm = syserr; // Send back converted error string LocalFree(syserr); // Discard the error string after passing it on } *errNo = lasterr; // Save it erm.ToBSTR(errMessage); ::SetLastError(0); // Make sure last error is clear *gotErr = TRUE; return S_OK; }
STDMETHODIMP CUUEngine::get_OutputPath(BSTR *pVal) { MString wrk; ue.UUGetOption(UUOPT_SAVEPATH, NULL, wrk.GetBuffer(MAX_PATH + 4), MAX_PATH); wrk.ToBSTR(pVal); return S_OK; }
STDMETHODIMP CUUEngine::get_LibVersion(BSTR *pVal) { MString wrk; ue.UUGetOption(UUOPT_VERSION, NULL, wrk.GetBuffer(), MSTRING_DLEN); wrk += " " __DATE__ " " __TIME__; wrk.ToBSTR(pVal); return S_OK; }
STDMETHODIMP CUUEngine::get_DFileInfo(short row, BSTR *pVal) { MString wrk; HRESULT hr = ue.GetInfo(row, wrk); if (hr != S_OK) return(hr); wrk.ToBSTR(pVal); return(S_OK); }
STDMETHODIMP CUUEngine::get_DFile(short row, BSTR *pVal) { uulist *up = ue.GetUulp(row); MString res; if (up == NULL) return(CTL_E_INVALIDPROPERTYARRAYINDEX); res = (up->filename == NULL || (up->state & UUFILE_NODATA)) ? "(No Data)" : up->filename; res.ToBSTR(pVal); return S_OK; }
STDMETHODIMP CUUEngine::get_DFileStatus(short row, BSTR *pVal) { MString wrk; // Accumulator for "State" int testpat; struct state_mask { int maskbits; char *meaning; } *smp; static struct state_mask mask_list[] ={ UUFILE_READ, "Read in", /* Read in, but not further processed */ UUFILE_MISPART, "Missing Parts", /* Missing Part(s) detected */ UUFILE_NOBEGIN, "No Begin found", /* No 'begin' found */ UUFILE_NOEND, "No End found", /* No 'end' found */ UUFILE_NODATA, "No Data in file", /* File does not contain valid uudata */ UUFILE_OK, "Ready to decode", /* All Parts found, ready to decode */ UUFILE_ERROR, "Error during decoding", /* Error while decoding */ UUFILE_DECODED, "Decoded OK" /* Successfully decoded */ }; static char *enc_list[] ={ // Encoding list "UU Encoded", "Mime-Base64 Encoded", "XX Encoded", "BinHex Encoded", "Plain Text", "Quoted-Printable" }; uulist *lup = ue.GetUulp(row); if (lup == NULL) return(CTL_E_INVALIDPROPERTYARRAYINDEX); wrk = (lup->uudet > 0) ? enc_list[lup->uudet-1] : "(No encoding)"; // Copy the encoding type testpat = lup->state; // Read the Test Pattern smp = mask_list; // Point to the mask list for (int i=(sizeof(mask_list) / sizeof(struct state_mask)); i>0; i--, smp++) if (testpat & smp->maskbits) { // This state is on wrk += ", "; // Add a comma wrk += smp->meaning; // Append the definition } if (lup->misparts != NULL) { // There is a missing-parts list bool first = true; char cbuf[16]; wrk += "; Missing parts: "; for (int *iptr=lup->misparts; *iptr != 0; iptr++) { // List ends with 0 if (first) first = false; else wrk += ","; wrk += _itoa(*iptr, cbuf, 10); } } if (lup->thisfile != NULL) { // There's a list of parts attached to this MString cbuf; // Compare buffer is empty char *cp; bool first = true; for (uufile *ufp=lup->thisfile; ufp != NULL; ufp=ufp->NEXT) if (ufp->data != NULL && ufp->data->sfname != NULL) { // Something to do. if (ufp->data->sfname[0] == EOS || cbuf == ufp->data->sfname) continue; // We've already counted this file cbuf = ufp->data->sfname; if (first) { first = false; wrk += "; From: "; } else wrk += ", "; wrk += ((cp = strrchr(ufp->data->sfname, '\\')) != NULL) ? cp+1 : ufp->data->sfname; } } wrk.ToBSTR(pVal); return S_OK; }
STDMETHODIMP CUUEngine::get_DFileDetail(short row, short itemno, short subscr, VARIANT *pVal) { MString cs; CComVariant lv; int *ip; struct _uufile *ufp; long lct; uulist *l = ue.GetUulp(row); if (l == NULL) return(CTL_E_INVALIDPROPERTYARRAYINDEX); switch (itemno) { case UUVBLD_STATE: lv = l->state; break; case UUVBLD_MODE: lv = l->mode; break; case UUVBLD_BEGIN: lv = (short) l->begin; break; case UUVBLD_END: lv = (short) l->end; break; case UUVBLD_UUDET: lv = l->uudet; break; case UUVBLD_FLAGS: lv = (short) l->flags; break; case UUVBLD_SIZE: lv = l->size; break; case UUVBLD_FILEN: cs = l->filename; break; case UUVBLD_SUBF: cs = l->subfname; break; case UUVBLD_MIMEID: cs = l->mimeid; break; case UUVBLD_MIMETYPE: cs = l->mimetype; break; case UUVBLD_BINFILE: cs = l->binfile; break; case UUVBLD_HAVEPART: case UUVBLD_MISSPART: if (subscr < 0 || subscr > 255) return(CTL_E_INVALIDPROPERTYARRAYINDEX); ip = ((itemno == UUVBLD_HAVEPART) ? l->haveparts : l->misparts) + subscr; if (IsBadReadPtr(ip, sizeof(int))) return(CTL_E_INVALIDPROPERTYARRAYINDEX); lv = (short) *ip; break; case UUVBLD_UFPART: if (subscr < 0 || subscr > 255) return(CTL_E_INVALIDPROPERTYARRAYINDEX); for (ufp=l->thisfile; ufp != NULL && subscr > 0; subscr--) ufp = ufp->NEXT; if (ufp == NULL) return(CTL_E_INVALIDPROPERTYARRAYINDEX); lv = ufp->partno; break; case UUVBLD_UFRSUBJ: case UUVBLD_UFRORG: case UUVBLD_UFRSFN: case UUVBLD_UFRSTART: // uulist.thisfile[subscr].data.start case UUVBLD_UFRLEN: // uulist.thisfile[subscr].data.length if (subscr < 0 || subscr > 255) return(CTL_E_INVALIDPROPERTYARRAYINDEX); for (ufp=l->thisfile; ufp != NULL && subscr > 0; subscr--) ufp = ufp->NEXT; if (ufp == NULL || ufp->data == NULL) return(CTL_E_INVALIDPROPERTYARRAYINDEX); switch (itemno) { case UUVBLD_UFRSUBJ: cs = ufp->data->subject; break; case UUVBLD_UFRORG: cs = ufp->data->origin; break; case UUVBLD_UFRSFN: cs = ufp->data->sfname; break; case UUVBLD_UFRSTART: // uulist.thisfile[subscr].data.start lv = ufp->data->startpos; break; case UUVBLD_UFRLEN: // uulist.thisfile[subscr].data.length lv = ufp->data->length; break; } break; case UUVBLD_UFRCOUNT: // Figure out the number of parts this subsection has lct = 0; ufp = l->thisfile; while (ufp != NULL) { ufp = ufp->NEXT; lct++; } lv = lct; break; } if (!cs.IsEmpty()) // This is a string return { lv.vt = VT_BSTR; cs.ToBSTR(&lv.bstrVal); } lv.Copy(pVal); return S_OK; }