Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

893 lines
28 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1999 - 2000
  4. *
  5. * TITLE: image.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: RickTu
  10. *
  11. * DATE: 9/16/99
  12. *
  13. * DESCRIPTION: Image class that encapsulates stored images from the
  14. * streaming video device.
  15. *
  16. *****************************************************************************/
  17. #include <precomp.h>
  18. #pragma hdrstop
  19. CLSID g_clsidBMPEncoder = GUID_NULL;
  20. using namespace Gdiplus;
  21. /*****************************************************************************
  22. CImage constructor/desctructor
  23. <Notes>
  24. *****************************************************************************/
  25. CImage::CImage(LPCTSTR pszStillPath,
  26. BSTR bstrRootFullItemName,
  27. LPCTSTR pszPath,
  28. LPCTSTR pszName,
  29. LONG FolderType)
  30. : m_strRootPath(pszStillPath),
  31. m_strPathItem(pszPath),
  32. m_strName(pszName),
  33. m_bstrItemName(pszName),
  34. m_bstrRootFullItemName(bstrRootFullItemName),
  35. m_FolderType(FolderType),
  36. m_bImageTimeValid(FALSE),
  37. m_pThumb(NULL)
  38. {
  39. DBG_FN("CImage::CImage");
  40. CSimpleStringWide str;
  41. CSimpleStringWide strName(m_bstrItemName);
  42. //
  43. // First, we need to strip off the extensions
  44. // from the appropriate places
  45. //
  46. strName = strName.Left(strName.ReverseFind( TEXT('.') ));
  47. m_bstrItemName = CSimpleBStr(strName);
  48. str = bstrRootFullItemName;
  49. str.Concat(L"\\");
  50. str += CSimpleStringWide(m_bstrItemName);
  51. m_bstrFullItemName = str.String();
  52. }
  53. CImage::~CImage()
  54. {
  55. if (m_pThumb)
  56. {
  57. delete [] m_pThumb;
  58. }
  59. }
  60. /*****************************************************************************
  61. CImage::LoadImageInfo
  62. Loads information about the image such as its width, height, type, etc.
  63. *****************************************************************************/
  64. STDMETHODIMP
  65. CImage::LoadImageInfo( BYTE * pWiasContext )
  66. {
  67. ASSERT(pWiasContext != NULL);
  68. HRESULT hr = S_OK;
  69. LONG lBitsPerChannel = 0;
  70. LONG lBitsPerPixel = 0;
  71. LONG lWidth = 0;
  72. LONG lHeight = 0;
  73. LONG lChannelsPerPixel = 0;
  74. LONG lBytesPerLine = 0;
  75. Bitmap Image(CSimpleStringConvert::WideString(m_strPathItem));
  76. if (pWiasContext == NULL)
  77. {
  78. hr = E_POINTER;
  79. CHECK_S_OK2(hr, ("LoadImageInfo received a NULL pointer"));
  80. return hr;
  81. }
  82. else if (Image.GetLastStatus() != Ok)
  83. {
  84. hr = E_FAIL;
  85. CHECK_S_OK2(hr, ("CImage::LoadImageInfo failed to get the image information"
  86. "for file '%ls'", CSimpleStringConvert::WideString(m_strPathItem)));
  87. return hr;
  88. }
  89. if (hr == S_OK)
  90. {
  91. PixelFormat lFormat;
  92. lFormat = Image.GetPixelFormat();
  93. if ((lFormat == PixelFormat16bppGrayScale) ||
  94. (lFormat == PixelFormat16bppRGB555) ||
  95. (lFormat == PixelFormat16bppRGB565) ||
  96. (lFormat == PixelFormat16bppARGB1555))
  97. {
  98. lBitsPerPixel = 16;
  99. lBitsPerChannel = 5; // this is actually not completely correct for RGB565, but anyway...
  100. }
  101. else if (lFormat == PixelFormat24bppRGB)
  102. {
  103. lBitsPerPixel = 24;
  104. lBitsPerChannel = 8;
  105. }
  106. else if ((lFormat == PixelFormat32bppRGB) ||
  107. (lFormat == PixelFormat32bppARGB) ||
  108. (lFormat == PixelFormat32bppPARGB))
  109. {
  110. lBitsPerPixel = 32;
  111. lBitsPerChannel = 10; // well, video cap won't have alpha in it,
  112. }
  113. lWidth = (LONG) Image.GetWidth();
  114. lHeight = (LONG) Image.GetHeight();
  115. lChannelsPerPixel = 3;
  116. lBytesPerLine = lWidth * (lBitsPerPixel / 8);
  117. }
  118. if (hr == S_OK)
  119. {
  120. PROPSPEC propSpecs[7];
  121. PROPVARIANT propVars[7];
  122. ZeroMemory(propSpecs, sizeof(propSpecs));
  123. // WIA_IPA_DATATYPE
  124. propSpecs[0].ulKind = PRSPEC_PROPID;
  125. propSpecs[0].propid = WIA_IPA_DATATYPE;
  126. propVars[0].vt = VT_I4;
  127. propVars[0].lVal = WIA_DATA_COLOR;
  128. // WIA_IPA_DEPTH
  129. propSpecs[1].ulKind = PRSPEC_PROPID;
  130. propSpecs[1].propid = WIA_IPA_DEPTH;
  131. propVars[1].vt = VT_I4;
  132. propVars[1].lVal = lBitsPerPixel;
  133. // WIA_IPA_PIXELS_PER_LINE
  134. propSpecs[2].ulKind = PRSPEC_PROPID;
  135. propSpecs[2].propid = WIA_IPA_PIXELS_PER_LINE;
  136. propVars[2].vt = VT_I4;
  137. propVars[2].lVal = lWidth;
  138. // WIA_IPA_NUMBER_OF_LINES
  139. propSpecs[3].ulKind = PRSPEC_PROPID;
  140. propSpecs[3].propid = WIA_IPA_NUMBER_OF_LINES;
  141. propVars[3].vt = VT_I4;
  142. propVars[3].lVal = lHeight;
  143. // WIA_IPA_CHANNELS_PER_PIXEL
  144. propSpecs[4].ulKind = PRSPEC_PROPID;
  145. propSpecs[4].propid = WIA_IPA_CHANNELS_PER_PIXEL;
  146. propVars[4].vt = VT_I4;
  147. propVars[4].lVal = lChannelsPerPixel;
  148. // WIA_IPA_BITS_PER_CHANNEL
  149. propSpecs[5].ulKind = PRSPEC_PROPID;
  150. propSpecs[5].propid = WIA_IPA_BITS_PER_CHANNEL;
  151. propVars[5].vt = VT_I4;
  152. propVars[5].lVal = lBitsPerChannel;
  153. // WIA_IPA_BYTES_PER_LINE
  154. propSpecs[6].ulKind = PRSPEC_PROPID;
  155. propSpecs[6].propid = WIA_IPA_BYTES_PER_LINE;
  156. propVars[6].vt = VT_I4;
  157. propVars[6].lVal = lBytesPerLine;
  158. // write the values of the properties.
  159. hr = wiasWriteMultiple(pWiasContext,
  160. sizeof(propVars) / sizeof(propVars[0]),
  161. propSpecs,
  162. propVars);
  163. CHECK_S_OK2(hr, ("CImage::LoadImageInfo, failed to write image properties"));
  164. }
  165. return hr;
  166. }
  167. /*****************************************************************************
  168. CImage::SetItemSize
  169. Call wia to calc new item size
  170. *****************************************************************************/
  171. STDMETHODIMP
  172. CImage::SetItemSize(BYTE * pWiasContext,
  173. MINIDRV_TRANSFER_CONTEXT * pDrvTranCtx)
  174. {
  175. HRESULT hr;
  176. MINIDRV_TRANSFER_CONTEXT drvTranCtx;
  177. GUID guidFormatID;
  178. BOOL bWriteProps = (pDrvTranCtx == NULL);
  179. DBG_FN("CImage::SetItemSize");
  180. ZeroMemory(&drvTranCtx, sizeof(MINIDRV_TRANSFER_CONTEXT));
  181. if (!pDrvTranCtx)
  182. {
  183. pDrvTranCtx = &drvTranCtx;
  184. }
  185. hr = wiasReadPropGuid(pWiasContext,
  186. WIA_IPA_FORMAT,
  187. (GUID*)&(pDrvTranCtx->guidFormatID),
  188. NULL,
  189. FALSE);
  190. CHECK_S_OK2(hr,("wiasReadPropGuid( WIA_IPA_FORMAT )"));
  191. if (FAILED(hr))
  192. {
  193. return hr;
  194. }
  195. hr = wiasReadPropLong( pWiasContext,
  196. WIA_IPA_TYMED,
  197. (LONG*)&(pDrvTranCtx->tymed),
  198. NULL,
  199. FALSE
  200. );
  201. CHECK_S_OK2(hr,("wiasReadPropLong( WIA_IPA_TYMED )"));
  202. if (FAILED(hr))
  203. {
  204. return hr;
  205. }
  206. //
  207. // Wias works for DIB, and minidriver support native formats
  208. //
  209. if ((pDrvTranCtx->guidFormatID != WiaImgFmt_JPEG) &&
  210. (pDrvTranCtx->guidFormatID != WiaImgFmt_FLASHPIX) &&
  211. (pDrvTranCtx->guidFormatID != WiaImgFmt_TIFF))
  212. {
  213. //
  214. // Create the image from the file.
  215. //
  216. Bitmap BitmapImage(CSimpleStringConvert::WideString(m_strPathItem));
  217. if (Ok == BitmapImage.GetLastStatus())
  218. {
  219. //
  220. // Get the image's dimensions
  221. //
  222. UINT nSourceWidth = BitmapImage.GetWidth();
  223. UINT nSourceHeight = BitmapImage.GetHeight();
  224. if (nSourceWidth && nSourceHeight)
  225. {
  226. //
  227. // Fill in info for drvTranCtx
  228. //
  229. pDrvTranCtx->lCompression = WIA_COMPRESSION_NONE;
  230. pDrvTranCtx->lWidthInPixels = nSourceWidth;
  231. pDrvTranCtx->lLines = nSourceHeight;
  232. pDrvTranCtx->lDepth = 24;
  233. hr = wiasGetImageInformation( pWiasContext, 0, pDrvTranCtx );
  234. //
  235. // We need to write out the item size based on
  236. // the JPEG converted to a BMP. But we only need
  237. // to do this if the incoming context was NULL.
  238. //
  239. if (bWriteProps)
  240. {
  241. hr = wiasWritePropLong( pWiasContext,
  242. WIA_IPA_ITEM_SIZE,
  243. pDrvTranCtx->lItemSize
  244. );
  245. CHECK_S_OK2(hr,("wiasWritePropLong( WIA_IPA_ITEM_SIZE )"));
  246. hr = wiasWritePropLong( pWiasContext,
  247. WIA_IPA_BYTES_PER_LINE,
  248. pDrvTranCtx->cbWidthInBytes
  249. );
  250. CHECK_S_OK2(hr,("wiasWritePropLong( WIA_IPA_BYTES_PER_LINE )"));
  251. }
  252. }
  253. else
  254. {
  255. DBG_ERR(("nSourceWidth OR nSourceHeight were zero"));
  256. hr = E_FAIL;
  257. }
  258. }
  259. else
  260. {
  261. DBG_ERR(("Ok == BitmapImage.GetLastStatus failed"));
  262. hr = E_FAIL;
  263. }
  264. }
  265. else
  266. {
  267. CMappedView cmv( ActualImagePath(), 0, OPEN_EXISTING );
  268. LARGE_INTEGER liSize = cmv.FileSize();
  269. ULONG ulSize;
  270. if (liSize.HighPart)
  271. {
  272. ulSize = 0;
  273. DBG_ERR(("The file was bigger than 4GB!!!"));
  274. }
  275. else
  276. {
  277. //
  278. // We could truncate here, I know, but that would have to be one huge file...
  279. // Anyway, the size wouldn't fit in te properties, which expects a LONG
  280. //
  281. ulSize = (ULONG)liSize.LowPart;
  282. }
  283. pDrvTranCtx->lItemSize = ulSize;
  284. pDrvTranCtx->cbWidthInBytes = 0;
  285. if (bWriteProps)
  286. {
  287. //
  288. // We need to write out the item size based on the file size...
  289. //
  290. hr = wiasWritePropLong(pWiasContext,
  291. WIA_IPA_ITEM_SIZE,
  292. ulSize);
  293. CHECK_S_OK2(hr,("wiasWritePropLong( WIA_IPA_ITEM_SIZE )"));
  294. hr = wiasWritePropLong(pWiasContext,
  295. WIA_IPA_BYTES_PER_LINE,
  296. 0);
  297. }
  298. CHECK_S_OK2(hr,("wiasWritePropLong( WIA_IPA_BYTES_PER_LINE )"));
  299. }
  300. CHECK_S_OK(hr);
  301. return hr;
  302. }
  303. /*****************************************************************************
  304. CImage::LoadThumbnail
  305. Loads (or creates if not already present) the thumbnail for this item.
  306. We also write the thumbnail as a property for this item.
  307. *****************************************************************************/
  308. STDMETHODIMP
  309. CImage::LoadThumbnail( BYTE * pWiasContext )
  310. {
  311. HRESULT hr = E_FAIL;
  312. DBG_FN("CImage::LoadThumbnail");
  313. //
  314. // Only create the thumbnail if we haven't done so already
  315. //
  316. if (!m_pThumb)
  317. {
  318. Status StatusResult = Ok;
  319. //
  320. // Open the source image and make sure it is OK
  321. //
  322. Bitmap SourceImage( CSimpleStringConvert::WideString(m_strPathItem) );
  323. StatusResult = SourceImage.GetLastStatus();
  324. if (Ok == StatusResult)
  325. {
  326. //
  327. // Create the scaled bitmap and make sure it is OK
  328. //
  329. Bitmap ScaledImage(THUMB_WIDTH, THUMB_HEIGHT);
  330. StatusResult = ScaledImage.GetLastStatus();
  331. if (Ok == StatusResult)
  332. {
  333. //
  334. // Get a graphics to render the scaled image to and make sure it isn't NULL
  335. //
  336. Graphics *pScaledGraphics = Graphics::FromImage(&ScaledImage);
  337. if (pScaledGraphics)
  338. {
  339. //
  340. // Make sure it is valid
  341. //
  342. StatusResult = pScaledGraphics->GetLastStatus();
  343. if (StatusResult == Ok)
  344. {
  345. //
  346. // Draw the image scaled to thumbnail size
  347. //
  348. StatusResult = pScaledGraphics->DrawImage(&SourceImage, 0, 0, THUMB_WIDTH, THUMB_HEIGHT );
  349. if (Ok == StatusResult)
  350. {
  351. //
  352. // Create a bitmap to hold the flipped thumbnail and make sure it is OK
  353. //
  354. Bitmap FlippedImage(THUMB_WIDTH, THUMB_HEIGHT);
  355. StatusResult = FlippedImage.GetLastStatus();
  356. if (Ok == StatusResult)
  357. {
  358. //
  359. // Create a graphics object to render the flipped image to and make sure it isn't NULL
  360. //
  361. Graphics *pFlippedGraphics = Graphics::FromImage(&FlippedImage);
  362. if (pFlippedGraphics)
  363. {
  364. //
  365. // Make sure it is valid
  366. //
  367. StatusResult = pFlippedGraphics->GetLastStatus();
  368. if (Ok == StatusResult)
  369. {
  370. //
  371. // Set up the parallelogram to flip the image
  372. //
  373. Point SourcePoints[3];
  374. SourcePoints[0].X = 0;
  375. SourcePoints[0].Y = THUMB_HEIGHT;
  376. SourcePoints[1].X = THUMB_WIDTH;
  377. SourcePoints[1].Y = THUMB_HEIGHT;
  378. SourcePoints[2].X = 0;
  379. SourcePoints[2].Y = 0;
  380. //
  381. // Draw the image, flipped
  382. //
  383. StatusResult = pFlippedGraphics->DrawImage(&ScaledImage, SourcePoints, 3);
  384. if (StatusResult == Ok)
  385. {
  386. //
  387. // Get the scaled and flipped image bits
  388. //
  389. Rect rcThumb( 0, 0, THUMB_WIDTH, THUMB_HEIGHT );
  390. BitmapData BitmapData;
  391. // This ifdef is due to an API change in GDI+. Notice
  392. // that the first param to LockBits in the new version
  393. // takes a ptr to RECT. Old version takes a reference
  394. // to a RECT.
  395. #ifdef DCR_USE_NEW_293849
  396. StatusResult = FlippedImage.LockBits( &rcThumb, ImageLockModeRead, PixelFormat24bppRGB, &BitmapData );
  397. #else
  398. StatusResult = FlippedImage.LockBits( rcThumb, ImageLockModeRead, PixelFormat24bppRGB, &BitmapData );
  399. #endif
  400. if (Ok == StatusResult)
  401. {
  402. //
  403. // Allocate the thumbnail data
  404. //
  405. m_pThumb = new BYTE[THUMB_SIZE_BYTES];
  406. if (m_pThumb)
  407. {
  408. //
  409. // Copy the thumbnail data over
  410. //
  411. CopyMemory( m_pThumb, BitmapData.Scan0, THUMB_SIZE_BYTES );
  412. }
  413. else
  414. {
  415. hr = E_OUTOFMEMORY;
  416. CHECK_S_OK2(hr, ("m_pThumb is NULL, couldn't allocate memory"));
  417. }
  418. //
  419. // Unlock the bits
  420. //
  421. FlippedImage.UnlockBits( &BitmapData );
  422. }
  423. else
  424. {
  425. DBG_ERR(("FlippedImage.LockBits( &rcThumb, ImageLockModeRead, PixelFormat24bppRGB, &BitmapData ) failed"));
  426. }
  427. }
  428. else
  429. {
  430. DBG_ERR(("pFlippedGraphics->DrawImage(&ScaledImage, SourcePoints, 3) failed"));
  431. }
  432. }
  433. else
  434. {
  435. DBG_ERR(("Ok == pFlippedGraphics->GetLastStatus() failed = '%d' (0x%08x)",
  436. StatusResult, StatusResult));
  437. }
  438. //
  439. // Free the graphics object
  440. //
  441. delete pFlippedGraphics;
  442. }
  443. else
  444. {
  445. DBG_ERR(("Graphics *pFlippedGraphics = Graphics::FromImage(&FlippedImage); returned NULL"));
  446. }
  447. }
  448. else
  449. {
  450. DBG_ERR(("Ok == FlippedImage.GetLastStatus() failed = '%d',(0x%08x)",
  451. StatusResult, StatusResult));
  452. }
  453. }
  454. else
  455. {
  456. DBG_ERR(("pScaledGraphics->DrawImage(&SourceImage, 0, 0, THUMB_WIDTH, THUMB_HEIGHT ) failed"));
  457. }
  458. }
  459. else
  460. {
  461. DBG_ERR(("pScaledGraphics->GetLastStatus() failed = '%d' (0x%08x)",
  462. StatusResult, StatusResult));
  463. }
  464. //
  465. // Free the graphics object
  466. //
  467. delete pScaledGraphics;
  468. }
  469. else
  470. {
  471. DBG_ERR(("Graphics *pScaledGraphics = Graphics::FromImage(&ScaledImage); returned NULL"));
  472. }
  473. }
  474. else
  475. {
  476. DBG_ERR(("ScaledImage.GetLastStatus() failed = '%d' (0x%08x)",
  477. StatusResult, StatusResult));
  478. }
  479. }
  480. else
  481. {
  482. DBG_ERR(("SourceImage.GetLastStatus() failed = '%d' (0x%08x)",
  483. StatusResult, StatusResult));
  484. }
  485. }
  486. if (m_pThumb)
  487. {
  488. //
  489. // We have the bits, write them out as a property
  490. //
  491. PROPSPEC propSpec;
  492. PROPVARIANT propVar;
  493. PropVariantInit(&propVar);
  494. propVar.vt = VT_VECTOR | VT_UI1;
  495. propVar.caub.cElems = THUMB_SIZE_BYTES;
  496. propVar.caub.pElems = m_pThumb;
  497. propSpec.ulKind = PRSPEC_PROPID;
  498. propSpec.propid = WIA_IPC_THUMBNAIL;
  499. hr = wiasWriteMultiple(pWiasContext, 1, &propSpec, &propVar);
  500. CHECK_S_OK2(hr,("wiasWriteMultiple( WIA_IPC_THUMBNAIL )"));
  501. }
  502. else
  503. {
  504. if (SUCCEEDED(hr))
  505. {
  506. hr = E_FAIL;
  507. }
  508. }
  509. CHECK_S_OK(hr);
  510. return hr;
  511. }
  512. /*****************************************************************************
  513. CImage::InitImageInformation
  514. Called to initialize the properties for this image. In the process,
  515. we also load (or create if needed) the thumbnail for this item.
  516. *****************************************************************************/
  517. STDMETHODIMP
  518. CImage::InitImageInformation(BYTE *pWiasContext,
  519. LONG *plDevErrVal)
  520. {
  521. HRESULT hr = S_OK;
  522. SYSTEMTIME st;
  523. DBG_FN("CImage::InitImageInformation");
  524. //
  525. // Use WIA services to set the extended property access and
  526. // valid value information from gWiaPropInfoDefaults.
  527. //
  528. hr = wiasSetItemPropAttribs( pWiasContext,
  529. NUM_CAM_ITEM_PROPS,
  530. gPropSpecDefaults,
  531. gWiaPropInfoDefaults
  532. );
  533. //
  534. // Use WIA services to write image properties.
  535. //
  536. hr = wiasWritePropLong(pWiasContext, WIA_IPC_THUMB_WIDTH, ThumbWidth());
  537. CHECK_S_OK2(hr,("wiasWritePropLong( WIA_IPC_THUMB_WIDTH )"));
  538. hr = wiasWritePropLong(pWiasContext, WIA_IPC_THUMB_HEIGHT, ThumbHeight());
  539. CHECK_S_OK2(hr,("wiasWritePropLong( WIA_IPC_THUMB_HEIGHT )"));
  540. hr = wiasWritePropGuid(pWiasContext, WIA_IPA_PREFERRED_FORMAT, WiaImgFmt_JPEG);
  541. CHECK_S_OK2(hr,("wiasWritePropGuid( WIA_IPA_PREFERRED_FORMAT )"));
  542. GetImageTimeStamp( &st );
  543. hr = wiasWritePropBin( pWiasContext, WIA_IPA_ITEM_TIME, sizeof(SYSTEMTIME), (PBYTE)&st);
  544. CHECK_S_OK2(hr,("wiasWritePropBin( WIA_IPA_ITEM_TIME )"));
  545. //
  546. // calc item size
  547. //
  548. hr = SetItemSize(pWiasContext,NULL);
  549. CHECK_S_OK2(hr,("SetItemSize"));
  550. //
  551. // load thumbnail
  552. //
  553. hr = LoadThumbnail( pWiasContext );
  554. CHECK_S_OK2(hr,("LoadThumbnail"));
  555. //
  556. // Load additional image information such as the pixels per line,
  557. // number of lines, etc.
  558. //
  559. hr = LoadImageInfo(pWiasContext);
  560. CHECK_S_OK2(hr,("wiaSetItemPropAttribs"));
  561. return hr;
  562. }
  563. /*****************************************************************************
  564. CImage::bstrItemName
  565. Returns the item name in the form of a BSTR.
  566. *****************************************************************************/
  567. BSTR
  568. CImage::bstrItemName()
  569. {
  570. DBG_FN("CImage::bstrItemName");
  571. return m_bstrItemName;
  572. }
  573. /*****************************************************************************
  574. CImage::bstrFullItemName
  575. Returns the full item name in the form of a BSTR.
  576. *****************************************************************************/
  577. BSTR
  578. CImage::bstrFullItemName()
  579. {
  580. DBG_FN("CImage::bstrFullItemName");
  581. return m_bstrFullItemName;
  582. }
  583. /*****************************************************************************
  584. CImage::ThumbWidth
  585. returns the thumbnail width
  586. *****************************************************************************/
  587. LONG
  588. CImage::ThumbWidth()
  589. {
  590. DBG_FN("CImage::ThumbWidth");
  591. return THUMB_WIDTH;
  592. }
  593. /*****************************************************************************
  594. CImage::ThumbHeight
  595. returns the thumbnail height
  596. *****************************************************************************/
  597. LONG
  598. CImage::ThumbHeight()
  599. {
  600. DBG_FN("CImage::ThumbHeight");
  601. return THUMB_HEIGHT;
  602. }
  603. /*****************************************************************************
  604. CImage::ImageTimeStamp
  605. returns creation time of image
  606. *****************************************************************************/
  607. void
  608. CImage::GetImageTimeStamp(SYSTEMTIME * pst)
  609. {
  610. DBG_FN("CImage::ImageTimeStamp");
  611. if (!m_bImageTimeValid)
  612. {
  613. HANDLE hFile = CreateFile(m_strPathItem,
  614. GENERIC_READ,
  615. FILE_SHARE_READ | FILE_SHARE_WRITE,
  616. NULL,
  617. OPEN_EXISTING,
  618. FILE_ATTRIBUTE_NORMAL,
  619. NULL);
  620. if (hFile != INVALID_HANDLE_VALUE)
  621. {
  622. FILETIME ft;
  623. if (GetFileTime( hFile, &ft, NULL, NULL ))
  624. {
  625. FILETIME ftLocal;
  626. if (FileTimeToLocalFileTime(&ft, &ftLocal))
  627. {
  628. if (FileTimeToSystemTime( &ftLocal, &m_ImageTime ))
  629. {
  630. m_bImageTimeValid = TRUE;
  631. }
  632. }
  633. }
  634. CloseHandle( hFile );
  635. }
  636. else
  637. {
  638. DBG_ERR(("CreateFile( %ls ) failed, GLE = %d",
  639. m_strPathItem.String(), GetLastError()));
  640. //
  641. // default to filling in structure w/zeros
  642. //
  643. memset( pst, 0, sizeof(SYSTEMTIME) );
  644. }
  645. }
  646. if (m_bImageTimeValid && pst)
  647. {
  648. *pst = m_ImageTime;
  649. }
  650. }
  651. /*****************************************************************************
  652. CImage::ActualImagePath
  653. Returns filename path of actual image
  654. *****************************************************************************/
  655. LPCTSTR
  656. CImage::ActualImagePath()
  657. {
  658. DBG_FN("CImage::ActualImagePath");
  659. return m_strPathItem.String();
  660. }
  661. /*****************************************************************************
  662. CImage::DoDelete
  663. Deletes the file (and thumbail) from the disk.
  664. *****************************************************************************/
  665. HRESULT
  666. CImage::DoDelete()
  667. {
  668. HRESULT hr = S_OK;
  669. BOOL bResFile;
  670. DBG_FN("CImage::DoDelete");
  671. //
  672. // Make sure we have a file to delete...
  673. //
  674. if (!m_strPathItem.Length())
  675. {
  676. DBG_ERR(("filename for item is zero length!"));
  677. hr = E_INVALIDARG;
  678. }
  679. else
  680. {
  681. //
  682. // We've got an item, so delete it and the thumbnail file
  683. //
  684. bResFile = DeleteFile(m_strPathItem.String());
  685. if (!bResFile)
  686. {
  687. DBG_ERR(("DeleteFile( %ls ) failed, GLE = %d",
  688. m_strPathItem.String(),GetLastError()));
  689. }
  690. if (bResFile)
  691. {
  692. m_strPathItem = NULL;
  693. m_strRootPath = NULL;
  694. m_strName = NULL;
  695. m_bstrRootFullItemName = NULL;
  696. m_bstrFullItemName = NULL;
  697. m_bImageTimeValid = FALSE;
  698. }
  699. else
  700. {
  701. hr = HRESULT_FROM_WIN32(GetLastError());
  702. }
  703. }
  704. CHECK_S_OK(hr);
  705. return hr;
  706. }