Source code of Windows XP (NT5)
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.

139 lines
4.2 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. SxsPath.cpp
  5. Abstract:
  6. popular cousin of "String.cpp" and "Wheel.cpp"
  7. Author:
  8. Jay Krell (a-JayK) April 2000
  9. Revision History:
  10. --*/
  11. #include "stdinc.h"
  12. #include "fusiontrace.h"
  13. #include "fusionbuffer.h"
  14. #include "sxsntrtl.inl"
  15. #include "sxspath.h"
  16. /*-----------------------------------------------------------------------------
  17. Building on CFullPathSplitPointers, take two strings and split them up
  18. exactly as the SetupCopyQueue API wants them, into
  19. source root, root path, source name (base + extension)
  20. destination directory (root + path), destination name (base + extension)
  21. The output of this class is its public member data.
  22. -----------------------------------------------------------------------------*/
  23. BOOL
  24. CSetupCopyQueuePathParameters::Initialize(
  25. PCWSTR pszSource,
  26. PCWSTR pszDestination
  27. )
  28. {
  29. BOOL fSuccess = FALSE;
  30. FN_TRACE_WIN32(fSuccess);
  31. CStringBufferAccessor Accessor;
  32. IFW32FALSE_EXIT(m_sourceBuffer.Win32Assign(pszSource, (pszSource != NULL) ? ::wcslen(pszSource) : 0));
  33. IFW32FALSE_EXIT(m_destinationBuffer.Win32Assign(pszDestination, (pszDestination != NULL) ? ::wcslen(pszDestination) : 0));
  34. Accessor.Attach(&m_sourceBuffer);
  35. IFW32FALSE_EXIT(m_sourceSplit.Initialize(Accessor.GetBufferPtr()));
  36. Accessor.Detach();
  37. Accessor.Attach(&m_destinationBuffer);
  38. IFW32FALSE_EXIT(m_destinationSplit.Initialize(Accessor.GetBufferPtr()));
  39. Accessor.Detach();
  40. if (m_sourceSplit.m_rootEnd - m_sourceSplit.m_root == 3)
  41. {
  42. m_sourceRootStorage[0] = m_sourceBuffer[0];
  43. m_sourceRootStorage[1] = ':';
  44. m_sourceRootStorage[2] = CUnicodeCharTraits::PreferredPathSeparator();
  45. m_sourceRootStorage[3] = 0;
  46. m_sourceSplit.m_root = m_sourceRootStorage;
  47. m_sourceSplit.m_rootEnd = m_sourceRootStorage + 3;
  48. m_sourceRoot = m_sourceRootStorage;
  49. }
  50. else
  51. {
  52. ASSERT(::FusionpIsPathSeparator(*m_sourceSplit.m_rootEnd));
  53. *m_sourceSplit.m_rootEnd = 0;
  54. m_sourceRoot = m_sourceSplit.m_root;
  55. }
  56. if (m_sourceSplit.m_pathEnd != NULL)
  57. {
  58. *m_sourceSplit.m_pathEnd = 0;
  59. }
  60. if (m_sourceSplit.m_path != NULL)
  61. {
  62. m_sourcePath = m_sourceSplit.m_path;
  63. *m_sourceSplit.m_pathEnd = 0;
  64. }
  65. else
  66. {
  67. m_sourcePath = L"";
  68. }
  69. if (m_sourceSplit.m_base != NULL)
  70. {
  71. m_sourceName = m_sourceSplit.m_base;
  72. }
  73. else
  74. {
  75. m_sourceName = m_sourceSplit.m_extension - 1;
  76. }
  77. // sourceName runs to end of original string, so no terminal nul needs to be stored
  78. // destination is simpler, not as much worth all the splitting work.
  79. // again though, we don't want to write a nul over the slash in c:\ if
  80. // that string stands alone; we don't need a root here, so it's less likely,
  81. // but the case of returning the root+path of a file at the root..
  82. if (
  83. (m_destinationSplit.m_base != NULL
  84. && m_destinationSplit.m_base - m_destinationSplit.m_root == 3) // c:\foo.txt
  85. || (m_destinationSplit.m_extension != NULL
  86. && m_destinationSplit.m_extension - m_destinationSplit.m_root == 4) // c:\.txt
  87. )
  88. {
  89. ASSERT(m_destinationSplit.m_path == NULL);
  90. m_destinationDirectoryStorage[0] = m_destinationBuffer[0];
  91. m_destinationDirectoryStorage[1] = ':';
  92. m_destinationDirectoryStorage[2] = CUnicodeCharTraits::PreferredPathSeparator();
  93. m_destinationDirectoryStorage[3] = 0;
  94. m_destinationSplit.m_root = m_destinationDirectoryStorage;
  95. m_destinationSplit.m_rootEnd = m_destinationDirectoryStorage + 3;
  96. m_destinationDirectory = m_destinationDirectoryStorage;
  97. }
  98. else
  99. {
  100. m_destinationDirectory = m_destinationBuffer; // == m_destinationSplit.m_root
  101. }
  102. PWSTR destinationName; // temporarily mutable
  103. if (m_destinationSplit.m_base != NULL)
  104. {
  105. destinationName = m_destinationSplit.m_base;
  106. }
  107. else
  108. {
  109. // c:\.foo
  110. destinationName = m_destinationSplit.m_extension - 1;
  111. }
  112. ASSERT(::FusionpIsPathSeparator(*(destinationName - 1)));
  113. *(destinationName - 1) = 0;
  114. m_destinationName = destinationName; // now const
  115. fSuccess = TRUE;
  116. Exit:
  117. return fSuccess;
  118. }