horeah / PyCmd

Improved interactive experience for Windows' cmd.exe
GNU Lesser General Public License v3.0
18 stars 4 forks source link

Added pushd/popd support #13

Closed Spavid04 closed 8 months ago

Spavid04 commented 11 months ago

As the title says 🤷‍♂️

Spavid04 commented 11 months ago

I checked versions of cmd.exe from a random Windows XP up to Windows 11, 32 and 64 bit, and all seem to store the directory stack the same way: 3 global variables (that we can easily get from the pdb). I'm leaving it here if there's ever any desire to modify the proposed pushd/popd handling.

Rough C code:

// pointer-size aligned struct!
struct DirectoryStack
{
  char* Path;
  uint16 Zero; // seems to be always set to 0
  // uint8 Padding[]; // padding to reach 4-byte alignment on 32bit systems, and 8-byte alignment on 64bit
}

int MaxStackDepth; // we don't really care about this; i saw that it just needs to be 25 more than StrStackDepth
int StrStackDepth; // the current stack depth
struct DirectoryStack* SavedDirectoryStack; // this is already initialized by cmd

void Pushd(char* path)
{
  int i = StrStackDepth;
  StrStackDepth++;
  MaxStackDepth = StrStackDepth + 25;
  SavedDirectoryStack = realloc(SavedDirectoryStack, sizeof(struct DirectoryStack) * MaxStackDepth);
  SavedDirectoryStack[i].Path = path;
  SavedDirectoryStack[i].Zero = 0;
}
char* Popd()
{
  char* path = StrStackDepth[StrStackDepth - 1].Path;
  StrStackDepth--;
  MaxStackDepth = StrStackDepth + 25;
  SavedDirectoryStack = realloc(SavedDirectoryStack, sizeof(struct DirectoryStack) * MaxStackDepth);
  return path;
}

In the end I just emulated a bunch of pushd [path] commands before every actual command, and at the end, read the resulting stack. (running pushd without any argument prints the stack)